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'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?
getExternalStorageDirectory() always returns the internal storage regardless of whether the SD card is inserted or not. Also there are some phones that don't support external SD cards at all (Google Nexus 4, for example).
For api 28 and below, you need getExternalStoragePublicDirectory() method but it is deprecated. What if you don't want to use that deprecated method? Then you can use SAF file explorer(Intent#ACTION_OPEN_DOCUMENT).
Apps target Android 10 and higher are given scoped access into external storage. In this case, try using getExternalFilesDir() method or media store api to store the file. Or you could include MANAGE_EXTERNAL_STORAGE permission for your application to access the external storage.
getExternalFilesDir() It returns the path to files folder inside Android/data/data/your_package/ on your SD card. It is used to store any required files for your app (e.g. images downloaded from web or cache files). Once the app is uninstalled, any data stored in this folder is gone too. getExternalStorageDirectory()
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With