在安卓系统中获取外部SDC卡的正确路径。

问题描述 投票:0回答:4

我试图获得正确的路径到SD卡,是我的三星S4安卓设备内通过我的应用程序,但当我尝试上述路径。

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

但当我尝试上述路径时... 它得到了私有的非可写路径的存储emulated0 而不是正确的路径storagesdcard1。

我发现正确的路径通过文件资源管理器使用Android设备监视器,但我不想硬编码的路径,因为路径可能是不同的设备。

亲切的问候

java android storage android-sdcard
4个回答
4
投票

对于所有设备

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%有效,在多个设备上测试。


3
投票

根据之前的回答,外置SD卡的路径其实随着不同的设备制造商而有所不同。

"Environment.getExternalStorageDirectory() 指的是设备制造商认为是 "外部存储 "的任何东西。在一些设备上,这是可移动媒体,如SD卡。在一些设备上,这是设备上闪存的一部分。在这里,"外部存储 "指的是 "安装在主机上时,通过USB大容量存储模式可以访问的东西",至少对于Android 1.x和2.x.但问题是关于外部SD。如何获得类似 "mntsdcardexternal_sd "这样的路径(不同设备可能会有所不同)?"Android没有 "外部SD "的概念,除了上面描述的外部存储外,如果设备制造商选择将外部存储作为板载闪存,并且也有SD卡,你需要联系该制造商,以确定是否可以使用SD卡(不能保证)以及使用它的规则,例如为它使用什么路径。"

根据 这个 的答案。

所以,没有绝对的方法可以通过代码获得这个路径。


1
投票

正如gilonm所提到的,外部(可移动)Sd路径因设备而异,但我写了一个方法,它遍历了不同厂商使用的所有不同ext路径,然后找到完全匹配的路径。

如果没有找到路径,它会返回空字符串。如果找到了路径,你还需要验证是否插入了卡。通过检查该路径上是否存在子文件夹)。

注:我用的是 流支持 库,所以你需要下载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];
}

P.S. 我在一些HTC和Samsung设备上进行了测试和验证。


0
投票

这个函数将返回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;
}
© www.soinside.com 2019 - 2024. All rights reserved.