簡體   English   中英

在android中獲取外部SDCard的正確路徑

[英]Get correct path to External SDCard in android

我正在嘗試通過我的應用程序獲取到我的 samsung s4 android 設備內的 SD 卡的正確路徑,但是當我嘗試上述路徑時:

  String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath();
        String pathTwo = Environment.getExternalStorageDirectory().getAbsolutePath();
        String path3 = getApplicationContext().getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath();

它獲取/storage/emulated/0的私有不可寫路徑而不是storage/sdcard1的正確路徑

我使用 Android 設備監視器通過文件資源管理器找到了正確的路徑,但我不想硬編碼路徑,因為路徑可能因設備而異。

親切的問候

適用於所有設備

String sSDpath = null;
            File   fileCur = null;
            for( String sPathCur : Arrays.asList( "MicroSD","external_SD","sdcard1","ext_card", "external_sd", "ext_sd", "external", "extSdCard",  "externalSdCard")) // external sdcard
             {

               fileCur = new File( "/mnt/", sPathCur);
               if( fileCur.isDirectory() && fileCur.canWrite())
                 {
                   sSDpath = fileCur.getAbsolutePath();
                   break;
                 }
               if( sSDpath == null)  {
               fileCur = new File( "/storage/", sPathCur);
               if( fileCur.isDirectory() && fileCur.canWrite())
                 {
                   sSDpath = fileCur.getAbsolutePath();
                   break;
                 }
               }
               if( sSDpath == null)  {
               fileCur = new File( "/storage/emulated", sPathCur);
               if( fileCur.isDirectory() && fileCur.canWrite())
                 {
                   sSDpath = fileCur.getAbsolutePath();
Log.e("path",sSpath);
                   break;
                 }
               }
             }

100% 工作,在多個設備上測試。

根據之前的回答,外部 SD 卡的路徑實際上因設備制造商而異。

Environment.getExternalStorageDirectory()指的是設備制造商認為是“外部存儲”的任何東西。在某些設備上,這是可移動媒體,如 SD 卡。在某些設備上,這是設備上閃存的一部分。這里, “外部存儲”的意思是“安裝在主機上時可通過 USB 大容量存儲模式訪問的東西”,至少對於 Android 1.x 和 2.x。但問題是關於外部 SD。如何獲得像“/ mnt/sdcard/external_sd”(它可能因設備而異)?除了如上所述的外部存儲之外,Android 沒有“外部 SD”的概念。如果設備制造商選擇將外部存儲作為板載閃存並且還有 SD 卡,您需要聯系該制造商以確定您是否可以使用 SD 卡(不保證)以及使用它的規則是什么,例如使用什么路徑。”

基於這個答案。

因此,沒有絕對的方法可以通過代碼獲取此路徑。

正如 gilonm 提到的,外部(可移動)Sd 路徑因設備而異,但我編寫了一個方法,它遍歷不同制造商使用的所有不同 ext 路徑,然后找到完全匹配的。

如果找不到路徑,則返回空字符串。 如果找到路徑,您還需要驗證是否插入了卡。 (通過檢查該路徑上是否存在子文件夾)

注意:我在方法中使用了StreamSupport庫,因此您需要下載 jar 文件並將其添加到項目的 libs 文件夾中,就這樣,它會起作用!

   public static String getExternalSdPath(Context context) {
    List<String> listOfFoldersToSearch = Arrays.asList("/storage/", "/mnt/", "/removable/", "/data/");
    final List<String> listOf2DepthFolders = Arrays.asList("sdcard0", "media_rw", "removable");
    final List<String> listOfExtFolders = Arrays.asList("sdcard1", "extsdcard", "external_sd", "microsd", "emmc", "ext_sd", "sdext",
            "sdext1", "sdext2", "sdext3", "sdext4");
    final String[] thePath = {""};
    Optional<File> optional = StreamSupport.stream(listOfFoldersToSearch)
            .filter(new Predicate<String>() {
                @Override
                public boolean test(final String s) {
                    File folder = new File(s);
                    return folder.exists() && folder.isDirectory();
                }
            }) //I got the ones that exist and are directories
            .flatMap(new Function<String, Stream<File>>() {
                @Override
                public Stream<File> apply(final String s) {
                    try {
                        List<File> files = Arrays.asList(new File(s).listFiles());
                        return StreamSupport.stream(files);
                    } catch (NullPointerException e) {
                        return StreamSupport.stream(new ArrayList<File>());
                    }
                }
            }) //I got all sub-dirs of the main folders
            .flatMap(new Function<File, Stream<File>>() {
                @Override
                public Stream<File> apply(final File file1) {
                    if (listOf2DepthFolders.contains(file1.getName()
                            .toLowerCase())) {
                        try {
                            List<File> files = Arrays.asList(file1.listFiles());
                            return StreamSupport.stream(files);
                        } catch (NullPointerException e) {
                            return StreamSupport.stream(Collections.singletonList(file1));
                        }
                    } else
                        return StreamSupport.stream(Collections.singletonList(file1));
                }
            }) //Here I got all the 2 depth and 3 depth folders
            .filter(new Predicate<File>() {
                @Override
                public boolean test(final File o) {
                    return listOfExtFolders.contains(o.getName()
                            .toLowerCase());
                }
            })
            .findFirst();

    optional.ifPresent(new Consumer<File>() {
        @Override
        public void accept(final File file) {
            thePath[0] = file.getAbsolutePath();
        }
    });

    Log.e("Path", thePath[0]);

    try {
        ContextCompat.getExternalFilesDirs(context, null);
    } catch (Exception e) {
        Log.e("PathException", thePath[0]);
    }
    return thePath[0];
}

PS 我在一些 HTC 和三星設備上測試並驗證了它。

此函數將返回 SD 卡路徑的路徑。

private String getExternalSdCard(){
   String finalPath = null;
   File sdCardFile = ContextCompat.getExternalFilesDirs(this, null)[1];
   String base = String.format("/Android/data/%s/files", getPackageName());

   String path = sdCardFile.getAbsolutePath();
   if(path.contains(base)){
       finalPath = path.replace(base, "");
   }
   return finalPath;

}

獲取所有存儲列表。 使用循環

private String[] storages() {
    List<String> storages = new ArrayList<>();

    try {
        File[] externalStorageFiles = ContextCompat.getExternalFilesDirs(this, null);

        String base = String.format("/Android/data/%s/files", getPackageName());

        for (File file : externalStorageFiles) {
            try {
                if (file != null) {
                    String path = file.getAbsolutePath();

                    if (path.contains(base)) {
                        String finalPath = path.replace(base, "");

                        if (validPath(finalPath)) {
                            storages.add(finalPath);
                        }
                    }
                }
            } catch (Exception e) {
                CrashUtils.report(e);
            }
        }
    } catch (Exception e) {
        CrashUtils.report(e);
    }

    String[] result = new String[storages.size()];
    storages.toArray(result);

    return result;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM