15

On Android 4.4.2 Environment.getExternalStorageDirectory().getPath() returns /storage/emulated/0 but this path does not exist on my Nexus5 Android 4.4.2. Environment.getExternalStorageDirectory().getPath() worked up until Android 4.4.2.

How can I get the /sdcard path on Android 4.4.2?

Mridang Agarwalla
  • 43,201
  • 71
  • 221
  • 382
powder366
  • 4,351
  • 7
  • 47
  • 79

3 Answers3

20

This path does not exist on my Nexus5 Android 4.4.2.

Yes, it does, for your process at runtime.

For example, this sample project downloads a file to Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS). If you log the location at runtime, when running it on a Nexus 5, it is reported as /storage/emulated/0/Download. And the download succeeds.

If you are looking for /storage/emulated/0 via DDMS or adb shell, you will not find it. For those tools, default external storage is /mnt/shell/emulated/0. Hence, the downloaded file from the above sample appears in the /mnt/shell/emulated/0/Download directory.

AFAIK, the difference is tied to providing separate external storage to secondary accounts.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Thanks, I learned something new:-) Also I was looking in wrong corner because of my wrong assumption... – powder366 Dec 22 '13 at 22:49
  • I tried your code and the setDestinationInExternalPublicDir did not work on Samsung Galaxy S3 device. any idea? – Leebeedev May 24 '15 at 10:04
  • "If you log the location at runtime, when running it on a Nexus 5, it is reported as /storage/emulated/0/Download". When you say *log*, do you mean using `Log.d()` or similar and launching the app from an IDE like Android Studio so you can view the log output? Or how do you view the log output? – LarsH Jun 22 '15 at 20:04
  • @LarsH: "When you say log, do you mean using Log.d()..." -- yes. – CommonsWare Jun 22 '15 at 20:07
  • So, if I wanna read and write files onto my nexus 5 during runtime, I need the /storage/emulated/... path and when trying to load the files from the phone to my PC, I will need the /mnt/shell/... path? Is that right? – keinabel Sep 29 '16 at 12:48
  • @keinabel: it depends on the version of Android that your device runs. – CommonsWare Sep 29 '16 at 13:06
  • @CommonsWare 6.0.1 – keinabel Sep 29 '16 at 14:19
2

The Storage Options documentation says to use Environment.getExternalStorageDirectory() (as you are already correctly using). This function is available on all versions of Android.

Are you seeing it return a path that isn't actually available on a 4.2 device?

Please note (from Environment.getExternalStorageDirectory()):

Applications should not directly use this top-level directory, in order to avoid polluting the user's root namespace. Any files that are private to the application should be placed in a directory returned by Context.getExternalFilesDir, which the system will take care of deleting if the application is uninstalled. Other shared files should be placed in one of the directories returned by getExternalStoragePublicDirectory(String).

Writing to this path requires the WRITE_EXTERNAL_STORAGE permission, and starting in read access requires the READ_EXTERNAL_STORAGE permission, which is automatically granted if you hold the write permission.

Starting in KITKAT, if your application only needs to store internal data, consider using getExternalFilesDir(String) or getExternalCacheDir(), which require no permissions to read or write.

Community
  • 1
  • 1
NPike
  • 13,136
  • 12
  • 63
  • 80
  • 1
    Yes /storage/emulated/0 is not available on Nexus5, even though the function returns it. – powder366 Dec 22 '13 at 22:16
  • 1
    This is the most fractured feature of Android I've ever seen. Broken two of my apps from version 2.x to 4.x. – Pedantic Dec 22 '13 at 22:22
  • 1
    @NPike getExternalCacheDir() and getExternalFilesDir(String) has the same problem. – powder366 Dec 22 '13 at 22:24
  • @Powder366, Yes, Pedantic found the solution, he just wasn't sure of the Android version you were using. Click on the link he found. Read everything after "Starting in KITKAT..." and use the code sample after that paragraph to see how external storage is monitored. – Stephan Branczyk Dec 22 '13 at 22:34
  • I didn't add a link, lol. No, I haven't found a consistent solution that ranges from 2.x to 4.x. I have some users with phones that do not return a folder for external storage. – Pedantic Dec 22 '13 at 23:48
2

Sometimes /storage/emulated/0 can be written to, but reads fail... so tests for "writability" are not sufficient. This is such an annoying problem, I have come up with an equally annoying but effective solution. Hardcode "/mnt/sdcard" Yea, I said it.

Looks like someone else said it first ... storing android application data on SD Card

More joy... http://forums.bignerdranch.com/viewtopic.php?f=414&t=7407

Community
  • 1
  • 1
kandinski
  • 860
  • 1
  • 8
  • 13