Environment.getExternalStorageDirectory does not return the path to the removable storage
As of API level 8, it seems Android has redefined what "external" storage is. Reading through http://developer.android.com/reference/android/os/Environment.html, attached to the documentation for getExternalStorageDirectory
I see the comment: "don't be confused by the word 'external' here. This directory can better be thought as media/shared storage... In devices with multiple 'external' storage directories... , this directory represents the 'primary' external storage that the user will interact with."
My app writes files to the path obtained by getExternalStorageDirectory
, and I开发者_JAVA百科've had users ask for an option to write to their removable SD card instead. I had always assumed that getExternalStorageDirectory
returned the path to the removable SD card, but this is no longer true. How do I access the path to this SD card?
According to the source, getExternalStorageDirectory
is implemented to return whatever is set as "external storage" in the device environment:
public static File getExternalStorageDirectory() {
return EXTERNAL_STORAGE_DIRECTORY;
}
and EXTERNAL_STORAGE_DIRECTORY
is:
private static final File EXTERNAL_STORAGE_DIRECTORY
= getDirectory("EXTERNAL_STORAGE", "/sdcard");
static File getDirectory(String variableName, String defaultPath) {
String path = System.getenv(variableName);
return path == null ? new File(defaultPath) : new File(path);
}
In contrast, getExternalStoragePublicDirectory(String type)
requires one of these strings:
DIRECTORY_MUSIC, DIRECTORY_PODCASTS, DIRECTORY_RINGTONES, DIRECTORY_ALARMS, DIRECTORY_NOTIFICATIONS, DIRECTORY_PICTURES, DIRECTORY_MOVIES, DIRECTORY_DOWNLOADS, or DIRECTORY_DCIM. May not be null.
so it is not meant to return the sd-card root.
An alternative:
Finally, getExternalStorageState()
will return the filesystem mounted in /mnt/sdcard/
. According to CommonsWare in this answer: Find an external SD card location, there is no way to directly get the external sdcard (if it even exist).
An alternative would be to check isExternalStorageRemovable ()
and give a manual option if it is false.
For API 17 I get the following returns:
Environment.getExternalStoragePublicDirectory(Environment.MEDIA_MOUNTED)
returns:-------> /storage/sdcard0/mounted
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)
returns:-------> /storage/sdcard0/DCIM
Environment.getExternalStoragePublicDirectory(Environment.MEDIA_SHARED)
returns:-------> /storage/sdcard0/shared
Environment.MEDIA_MOUNTED
returns:-------> mounted
Environment.getExternalStorageDirectory()
returned:-------> /storage/sdcard0
All return location of internal phone memory.
To be sure you are accessing the sd card you can use:
System.getenv("SECONDARY_STORAGE")
however - please keep in mind that even if you set all the correct permissions in the manifest - The only place 3rd party apps are allowed to write on your external card are "their own directories" (i.e. /sdcard/Android/data/)
Try to write to anywhere else and you will get exception: EACCES (Permission denied)
精彩评论