可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I've been Googling around but it is sooooo hard to find what manufacturers/models use which path for sdcard/external storage.
- I am NOT talking about the internal storage path which can be found by:
Environment.getExternalStorageDirectory()
I know that getExternalStorageDirectory()
sometimes points to external sdcard on some devices.
Here's what I've found some common path for external path (Not sure which manufacturer uses which path):
/emmc
/mnt/sdcard/external_sd
/mnt/external_sd
/sdcard/sd
/mnt/sdcard/bpemmctest
/mnt/sdcard/_ExternalSD
/mnt/sdcard-ext
/mnt/Removable/MicroSD
/Removable/MicroSD
/mnt/external1
/mnt/extSdCard
/mnt/extsd
/mnt/usb_storage <-- usb flash mount
/mnt/extSdCard <-- usb flash mount
/mnt/UsbDriveA <-- usb flash mount
/mnt/UsbDriveB <-- usb flash mount
These are what I found by Googling around.
I need to scan entire internal + external storage + USB flash drive to look for a certain file. If I am missing any path, please add to the above list. If someone knows paths used by each manufacturers, please share with us.
回答1:
Good news! In KitKat there's now a public API for interacting with these secondary shared storage devices.
The new Context.getExternalFilesDirs()
and Context.getExternalCacheDirs()
methods can return multiple paths, including both primary and secondary devices. You can then iterate over them and check Environment.getStorageState()
and File.getFreeSpace()
to determine the best place to store your files. These methods are also available on ContextCompat
in the support-v4 library.
Also note that if you're only interested in using the directories returned by Context
, you no longer need the READ_
or WRITE_EXTERNAL_STORAGE
permissions. Going forward, you'll always have read/write access to these directories with no additional permissions required.
Apps can also continue working on older devices by end-of-lifing their permission request like this:
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
回答2:
I also started with a list like yours from somewhere (sorry couldn't find the original source) and continue to add some paths collected from user feedback. There are duplicate to the above list.
/storage/sdcard1 //!< Motorola Xoom
/storage/extsdcard //!< Samsung SGS3
/storage/sdcard0/external_sdcard // user request
/mnt/extsdcard
/mnt/sdcard/external_sd //!< Samsung galaxy family
/mnt/external_sd
/mnt/media_rw/sdcard1 //!< 4.4.2 on CyanogenMod S3
/removable/microsd //!< Asus transformer prime
/mnt/emmc
/storage/external_SD //!< LG
/storage/ext_sd //!< HTC One Max
/storage/removable/sdcard1 //!< Sony Xperia Z1
/data/sdext
/data/sdext2
/data/sdext3
/data/sdext4
/sdcard1 //Sony Xperia Z
/sdcard2 //HTC One M8s
/storage/microsd //ASUS ZenFone 2
For what you want to achieve (scanning all possible paths for certain files), I think it's quite impossible to do it this way (using a list of known paths). Some paths on same device even changed between android upgrade.
回答3:
Based on the paths oceanuz provided, I wrote a method, which locates the external storage path (ignoring the case) and returns it as a String.
Note: I used StreamSupport library inside my method, so in order for it to work, you'll need to download the jar file and add that to libs folder in your project and that's it.
public static String getExternalSdPath(Context context) {
List<String> listOfFoldersToSearch = Arrays.asList("/storage/", "/mnt/", "/removable/", "/data/");
List<String> listOf2DepthFolders = Arrays.asList("sdcard0", "media_rw", "removable");
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(s -> {
File folder = new File(s);
return folder.exists() && folder.isDirectory();
}) //I got the ones that exist and are directories
.flatMap(s -> {
try {
List<File> files = Arrays.asList(new File(s).listFiles());
return StreamSupport.stream(files);
} catch (NullPointerException e) {
return StreamSupport.stream(Collections.emptyList());
}
}) //I got all sub-dirs of the main folders
.flatMap(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(o -> listOfExtFolders.contains(o.getName().toLowerCase()))
.findFirst();
optional.ifPresent(file -> thePath[0] = file.getAbsolutePath());
Log.i("Path", thePath[0]);
return thePath[0];
}
This method will return an empty string if there is no Sd Card path found.
回答4:
I was trying to find path to my external SD card on Sony Xperia XA. I then installed ES File explorer and that clearly showed path to any folder, internal or external, in it's characteristics window. I found the path to external SD as /storage/C4EE-F3A3. I was trying to save output file from Python3 to external SD but it did not have permission to save anywhere other than Qpython folder in the internal SD.
回答5:
Have you tried:
Environment.getExternalStoragePublicDirectory.getExternalStorageDirectory(String type);
Where type is which directory defined by android you need like Environment.DIRECTORY_DOWNLOADS, which will give you the download directory
It's not "getExternalStorageDirectory" it's "getExternalStoragePublicDirectory". Note that for every android device it will return the place where storage happens (for example: /mnt/external_sd) worked on my transformer 101, a nexus 10 and a galaxy s2. I needed it to download a file on the storage
Here's the documentation http://developer.android.com/reference/android/os/Environment.html