`/storage/emulated/legacy/` vs `/storage/emulated/0/` vs `data/data/myApp'

Elad Benda picture Elad Benda · May 13, 2014 · Viewed 55.8k times · Source

I want to save in my app an imageFile

I want "Google+ cropper app" to use it.

But the later opens another image.

I guess it's permissions issue.

In my code i save here:

Is this external storage? Environment.getExternalStorageDirectory().getAbsolutePath() which returns: /storage/emulated/0/myApp/file1.tmp

using adb shell is see the file is actually saved in: /storage/emulated/legacy/myApp/file1.tmp

why is the difference?

should i use this place instead? Is this external storage?

getAppContext().getFilesDir().getParent() which returns: `data/data/myApp'

Answer

Squonk picture Squonk · May 13, 2014

Historically the difference between internal and external storage was as follows...

Internal: The internal flash storage of an Android device used to allocate private storage for each app. The storage allocated is protected to prevent access by any other app (except on rooted devices).

External: In many cases an SD card with no security restrictions, i.e., all apps can access all areas of "external" storage.

As new versions of Android have come along and new devices have increasingly more internal flash storage, the difference between internal and external is becoming blurred. For example my Nexus 7 doesn't have an SD card slot.

In the case of devices without true external storage, it's still necessary for Android to provide an emulated external storage in order to remain compatible with older apps. In other words the RAM is physically internal (non-removable) but a section of it is partitioned and the Android file-system APIs treat that partition as being "external" and world-readable.

As for the paths you see for external storage such as...

/storage/emulated/0/myApp/file1.tmp
/storage/emulated/legacy/myApp/file1.tmp

...one or other of those (possibly both) is a redirection or "virtual" path to the same part of the emulated external directory and file.

This is why it is essential to always use the correct API call to get access to files and directories rather than assuming a hard-coded path as it may well vary from device to device.

If you use Environment.getExternalStorageDirectory(), you can be confident that any other app which does the same will be able to get access to any files you create there.

If you use getFilesDir() then you are accessing the root of the internal storage allocated privately to your app and accessible only to your app (although, as I mentioned a rooted phone can access private / internal storage).