开发者

Environment.getExternalStorageDirectory does not return the path to the removable storage

开发者 https://www.devze.com 2023-03-07 01:04 出处:网络
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 ge

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)

0

精彩评论

暂无评论...
验证码 换一张
取 消