[英]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.