我正在尝试通过我的应用程序获取正确的路径到我的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的私有不可写路径而不是正确的存储路径/ sdcard1
我通过File explorer使用Android设备监视器找到了正确的路径,但我不想对路径进行硬编码,因为路径可能因设备而异。
亲切的问候
答案 0 :(得分: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%正常工作,在多台设备上进行测试。
答案 1 :(得分:3)
根据之前的回答,外部SD卡的路径实际上因设备制造商而异。
“Environment.getExternalStorageDirectory()
指的是设备制造商认为是”外部存储“的任何内容。在某些设备上,这是可移动媒体,如SD卡。在某些设备上,这是on的一部分-device flash。这里,“外部存储”意味着“安装在主机上时可通过USB大容量存储模式访问的东西”,至少对于Android 1.x和2.x.
但问题是关于外部SD。如何获得像“/ mnt / sdcard / external_sd”这样的路径(它可能因设备而异)?
除了外部存储之外,Android没有“外部SD”的概念,如上所述。
如果设备制造商已选择将外部存储设备作为板载闪存并且还具有SD卡,则需要与该制造商联系以确定是否可以使用SD卡(不保证)以及规则是什么使用它,比如使用它的路径。“
基于this回答。
所以,没有绝对的方法可以通过代码获得这条路径。
答案 2 :(得分:1)
正如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];
}
P.S。我在一些HTC和三星设备上测试并验证了它。
答案 3 :(得分: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;
}