Как получить путь SD_Card в android6.0 программно

Я пытаюсь проверить, есть ли у устройства внешнее хранилище или нет, используя внешний путь хранения, как показано ниже.

 if (new File("/ext_card/").exists()) {
        specialPath = "/ext_card/";
    } else if (new File("/mnt/sdcard/external_sd/").exists()) {
        specialPath = "/mnt/sdcard/external_sd/";
    } else if (new File("/storage/extSdCard/").exists()) {
        specialPath = "/storage/extSdCard/";
    } else if (new File("/mnt/extSdCard/").exists()) {
        specialPath = "/mnt/extSdCard/";
    } else if (new File("/mnt/sdcard/external_sd/").exists()) {
        specialPath = "/mnt/sdcard/external_sd/";
    } else if (new File("storage/sdcard1/").exists()) {
        specialPath = "storage/sdcard1/";
    }

Но в зефире я не нашел этот путь и, проверяя с помощью ES FILEMANAGER, они дают как хранилище /3263-3131 в Moto G 3-го поколения. Проверяйте другие устройства для производства зефира, которые отличаются друг от друга. Пожалуйста, помогите мне проверить, что у устройства для производства зефира есть внешнее хранилище или нет? и если найденное хранилище означает, как получить путь к этому внешнему хранилищу?

Примечание. - Я дал разрешение на хранение в своем приложении, а также разрешил разрешение на хранение в настройках моего приложения.

Спасибо заранее, и вы нашли ошибку в моем вопросе, пожалуйста, crt. еще раз спасибо.

Ответ 1

Вот мое решение, которое гарантированно будет работать до нуга Android 7.0:

/* returns external storage paths (directory of external memory card) as array of Strings */
public String[] getExternalStorageDirectories() {

        List<String> results = new ArrayList<>();

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { //Method 1 for KitKat & above
        File[] externalDirs = getExternalFilesDirs(null);
        String internalRoot = Environment.getExternalStorageDirectory().getAbsolutePath().toLowerCase();

        for (File file : externalDirs) {
            if(file==null) //solved NPE on some Lollipop devices
               continue;
            String path = file.getPath().split("/Android")[0];

            if(path.toLowerCase().startsWith(internalRoot))
               continue;

            boolean addPath = false;

            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                addPath = Environment.isExternalStorageRemovable(file);
            }
            else{
                addPath = Environment.MEDIA_MOUNTED.equals(EnvironmentCompat.getStorageState(file));
            }

            if(addPath){
                results.add(path);
            }
        }
    }

        if(results.isEmpty()) { //Method 2 for all versions
            // better variation of: http://stackoverflow.com/a/40123073/5002496
            String output = "";
            try {
                final Process process = new ProcessBuilder().command("mount | grep /dev/block/vold")
                .redirectErrorStream(true).start();
                process.waitFor();
                final InputStream is = process.getInputStream();
                final byte[] buffer = new byte[1024];
                while (is.read(buffer) != -1) {
                    output = output + new String(buffer);
                }
                is.close();
            } catch (final Exception e) {
                e.printStackTrace();
            }
            if(!output.trim().isEmpty()) {
                String devicePoints[] = output.split("\n");
                for(String voldPoint: devicePoints) {
                    results.add(voldPoint.split(" ")[2]);
                }
            }
        }

        //Below few lines is to remove paths which may not be external memory card, like OTG (feel free to comment them out)
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            for (int i = 0; i < results.size(); i++) {
                if (!results.get(i).toLowerCase().matches(".*[0-9a-f]{4}[-][0-9a-f]{4}")) {
                    Log.d(LOG_TAG, results.get(i) + " might not be extSDcard");
                    results.remove(i--);
                }
            }
        } else {
            for (int i = 0; i < results.size(); i++) {
                if (!results.get(i).toLowerCase().contains("ext") && !results.get(i).toLowerCase().contains("sdcard")) {
                    Log.d(LOG_TAG, results.get(i)+" might not be extSDcard");
                    results.remove(i--);
                }
            }
        }

        String[] storageDirectories = new String[results.size()];
        for(int i=0; i<results.size(); ++i) storageDirectories[i] = results.get(i);

        return storageDirectories;
    }

Ответ 2

Я нашел решение для этого здесь fooobar.com/questions/36372/...

Код -

public static HashSet<String> getExternalMounts() {
    final HashSet<String> out = new HashSet<String>();
    String reg = "(?i).*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4).*rw.*";
    String s = "";
    try {
        final Process process = new ProcessBuilder().command("mount")
                .redirectErrorStream(true).start();
        process.waitFor();
        final InputStream is = process.getInputStream();
        final byte[] buffer = new byte[1024];
        while (is.read(buffer) != -1) {
            s = s + new String(buffer);
        }
        is.close();
    } catch (final Exception e) {
        e.printStackTrace();
    }

    // parse output
    final String[] lines = s.split("\n");
    for (String line : lines) {
        if (!line.toLowerCase(Locale.US).contains("asec")) {
            if (line.matches(reg)) {
                String[] parts = line.split(" ");
                for (String part : parts) {
                    if (part.startsWith("/"))
                        if (!part.toLowerCase(Locale.US).contains("vold"))
                            out.add(part);
                }
            }
        }
    }
    return out;
}

Другой - это хак, который я нашел на той же странице -

private static final Pattern DIR_SEPORATOR = Pattern.compile("/");

/**
 * Raturns all available SD-Cards in the system (include emulated)
 *
 * Warning: Hack! Based on Android source code of version 4.3 (API 18)
 * Because there is no standart way to get it.
 * TODO: Test on future Android versions 4.4+
 *
 * @return paths to all available SD-Cards in the system (include emulated)
 */
public static String[] getStorageDirectories()
{
    // Final set of paths
    final Set<String> rv = new HashSet<String>();
    // Primary physical SD-CARD (not emulated)
    final String rawExternalStorage = System.getenv("EXTERNAL_STORAGE");
    // All Secondary SD-CARDs (all exclude primary) separated by ":"
    final String rawSecondaryStoragesStr = System.getenv("SECONDARY_STORAGE");
    // Primary emulated SD-CARD
    final String rawEmulatedStorageTarget = System.getenv("EMULATED_STORAGE_TARGET");
    if(TextUtils.isEmpty(rawEmulatedStorageTarget))
    {
        // Device has physical external storage; use plain paths.
        if(TextUtils.isEmpty(rawExternalStorage))
        {
            // EXTERNAL_STORAGE undefined; falling back to default.
            rv.add("/storage/sdcard0");
        }
        else
        {
            rv.add(rawExternalStorage);
        }
    }
    else
    {
        // Device has emulated storage; external storage paths should have
        // userId burned into them.
        final String rawUserId;
        if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)
        {
            rawUserId = "";
        }
        else
        {
            final String path = Environment.getExternalStorageDirectory().getAbsolutePath();
            final String[] folders = DIR_SEPORATOR.split(path);
            final String lastFolder = folders[folders.length - 1];
            boolean isDigit = false;
            try
            {
                Integer.valueOf(lastFolder);
                isDigit = true;
            }
            catch(NumberFormatException ignored)
            {
            }
            rawUserId = isDigit ? lastFolder : "";
        }
        // /storage/emulated/0[1,2,...]
        if(TextUtils.isEmpty(rawUserId))
        {
            rv.add(rawEmulatedStorageTarget);
        }
        else
        {
            rv.add(rawEmulatedStorageTarget + File.separator + rawUserId);
        }
    }
    // Add all secondary storages
    if(!TextUtils.isEmpty(rawSecondaryStoragesStr))
    {
        // All Secondary SD-CARDs splited into array
        final String[] rawSecondaryStorages = rawSecondaryStoragesStr.split(File.pathSeparator);
        Collections.addAll(rv, rawSecondaryStorages);
    }
    return rv.toArray(new String[rv.size()]);
}

Ответ 3

Эта библиотека решит мою проблему.

https://github.com/hendrawd/StorageUtil

Что я сделал, это:

private File directory;
String[] allPath;

allPath = StorageUtil.getStorageDirectories(this);
for (String path: allPath){
    directory = new File(path);
    Methods.update_Directory_Files(directory);
}

Methods.update_Directory_Files()

// Retrieving files from memory

public static void  update_Directory_Files(File directory) {

    //Get all file in storage
    File[] fileList = directory.listFiles();
    //check storage is empty or not
    if(fileList != null && fileList.length > 0)
    {
        for (int i=0; i<fileList.length; i++)
        {
            boolean restricted_directory = false;
            //check file is directory or other file
            if(fileList[i].isDirectory())
            {
                for (String path : Constant.removePath){
                    if (path.equals(fileList[i].getPath())) {
                        restricted_directory = true;
                        break;
                    }
                }
                if (!restricted_directory)
                    update_Directory_Files(fileList[i]);
            }
            else
            {
                String name = fileList[i].getName().toLowerCase();
                for (String ext : Constant.videoExtensions){
                    //Check the type of file
                    if(name.endsWith(ext))
                    {
                        //first getVideoDuration
                        String videoDuration = Methods.getVideoDuration(fileList[i]);
                        long playbackPosition;
                        long percentage = C.TIME_UNSET;
                        FilesInfo.fileState state;

                        /*First check video already played or not. If not then state is NEW
                         * else load playback position and calculate percentage of it and assign it*/

                        //check it if already exist or not if yes then start from there else start from start position
                        int existIndex = -1;
                        for (int j = 0; j < Constant.filesPlaybackHistory.size(); j++) {
                            String fListName = fileList[i].getName();
                            String fPlaybackHisName = Constant.filesPlaybackHistory.get(j).getFileName();
                            if (fListName.equals(fPlaybackHisName)) {
                                existIndex = j;
                                break;
                            }
                        }

                        try {
                            if (existIndex != -1) {
                                //if true that means file is not new
                                state = FilesInfo.fileState.NOT_NEW;
                                //set playbackPercentage not playbackPosition
                                MediaMetadataRetriever retriever = new MediaMetadataRetriever();
                                retriever.setDataSource(fileList[i].getPath());
                                String time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
                                retriever.release();

                                int duration = Integer.parseInt(time);
                                playbackPosition = Constant.filesPlaybackHistory.get(existIndex).getPlaybackPosition();

                                if (duration > 0)
                                    percentage = 1000L * playbackPosition / duration;
                                else
                                    percentage = C.TIME_UNSET;

                            }
                            else
                                state = FilesInfo.fileState.NEW;

                            //playbackPosition have value in percentage
                            Constant.allMemoryVideoList.add(new FilesInfo(fileList[i],
                                    directory,videoDuration, state, percentage));

                            //directory portion
                            currentDirectory = directory.getPath();
                            unique_directory = true;

                            for(int j=0; j<directoryList.size(); j++)
                            {
                                if((directoryList.get(j).toString()).equals(currentDirectory)){
                                    unique_directory = false;
                                }
                            }

                            if(unique_directory){
                                directoryList.add(directory);
                            }

                            //When we found extension from videoExtension array we will break it.
                            break;

                        }catch (Exception e){
                            e.printStackTrace();
                            Constant.allMemoryVideoList.add(new FilesInfo(fileList[i],
                                    directory,videoDuration, FilesInfo.fileState.NOT_NEW, C.TIME_UNSET));
                        }

                    }
                }
            }
        }
    }
    Constant.directoryList = directoryList;
}

Ответ 4

в этом я имею redmi note prime 2. и у меня нет карты памяти. Когда я нашел путь и File [] externalDirs = getExternalFilesDirs (null); дать значение null второго значения для файла []. }