This question already has answers here:
Find location of a removable SD card
(24 answers)
Closed 6 years ago.
Long time iOS developer, advanced Android programmer (but not as advanced as I thought.. LOL)..
Trying to understand Android device storage options. On my android device I have an 14Gig SD Card.
When I write code
String strDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)+ File.separator + "MyFolder";
it gets placed in a "Documents folder" on the internal device (when viewed with File Manager).
The path appears to be
storage/emulated/0
and my sd card (acording to the File Manager) is
storage/extSdCard
Why does Environment.getExternalStoragePublicDirectory give me a path to my intneral card?
What am I missing that gets me to a path to store files to the external card. I think I understand part of this is do to OS changes in SD Card access in 4.1 but not sure what I'm missing.
I've read through Environment.getExternalStorageDirectory does not return the path to the removable storage and still not clear. My app currently stores files using getExternalStoragePublicDirectory, however my users are requesting they have the option of storing it on the SDCard instead?
Why does Environment.getExternalStoragePublicDirectory give me a path to my intneral card?
Because external storage is not removable storage. Neither of those are internal storage.
however my users are requesting they have the option of storing it on the SDCard instead?
On Android 4.4+, either use the Storage Access Framework (to allow the user to choose a storage location, including removable storage, Drive/Dropbox/other cloud providers, etc.), or use getExternalFilesDirs() on Context. The latter method returns a File[] — if there are 2+ elements in the array, all but the first are locations on removable storage that you can read from and write to. You cannot write to arbitrary locations on removable storage on devices that ship with Android 4.4+.
Related
getExternalFilesDir(null) is returning the path of the emulated sd card i.e internal to the phone but not the path removable sd card
how i can find the data directory of app on removable storage
'External' means not internal and internal means private if we translate Android English to real life English. External storage is the place that all apps can access and use.
Since the question is a bit vague then the answer must be.
SD card can be mapped to internal storage or external storage, but this is fairly new technology.
If you want to access SD card using in versions earlier than Android 5.0 (API 21) then you can use Environment.getExternalStorageDirectory();
Otherwise you must use Storage Access Framework to do it.
Background
Android had a lot of changes as to how to handle the SD-card and storage in general:
API 3 - you get all access, no permission needed
API 4-15 - you need to use WRITE_EXTERNAL_STORAGE, and you get all access.
API 16-18 - if you wish only to read, use READ_EXTERNAL_STORAGE
API 19-20 - you can't read or write to secondary external storage (SD-card), unless your app is a system app, or you have root.
API 21-22 - in order to access the SD-card, you need to ask the user for permission, and use the DocumentFile API instead of the File API. This raied a lot of questions, as I've written about here, here and here.
Starting with API 23 (Android 6), things seem to change yet again...
The problem
For API 23, there are at least 2 things that are new and are storage-related :
"Adoptable Storage Devices" - The user can optionally make the SD-card as something that's like the primary external storage.
As part of the new permissions mechanism (requesting permissions at runtime), it seems that storage is also a permission the user needs to confirm. This is for both READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE
Since there is no Android 6 device out there that has SD-card, and because the emulator itself doesn't really have the ability to use an SD-card, it's still impossible to know what's going on.
The questions
Will the SD-card get the access using the File-API instead of DocumentFile?
If I want access to all external storage paths (including SD-card), does this mean I need to request this permissions twice: one for the primary external storage and one for the SD-card?
Are files on the SD-card accessible in any way before the manual granting of the permission?
Suppose the user has chosen to use "Adoptable Storage Devices", what does it mean for the various functions that retrieve the paths of the app's files? For example : getFilesDir, getExternalFilesDir,... ? Would the oder of getExternalFilesDirs change because of it?
What happens to the files of the app when the user moves the app from/to the SD-card (using the "Adoptable Storage Devices") ? What about the app's files on the SD-card? Would they stay? Or would they move somewhere?
For example, if the app has "file1.txt" on the SD-card, on path "/storage/extSdCard/Android/data/appPackageName", and it has a file "file2.txt" (or even the same name) on the primary external storage on path "/storage/emulated/0/Android/data/appPackageName". After switching, what would happen for those files? How would they merge into a single folder, if at all?
When moving the app to the SD-card (using "Adoptable Storage Devices"), does it mean no internal storage will be used?
Let me answer Adoptable Storage Devices related questions:
Suppose the user has chosen to use "Adoptable Storage Devices", what does it mean for the various functions that retrieve the paths of
the app's files? For example : getFilesDir, getExternalFilesDir,... ?
Would the oder of getExternalFilesDirs change because of it?
When user choose to use SD card as "Adoptable Storage Device" (Format as internal), it means now that SD card is available only as Internal Storage i.e. no SD card available to store downloaded files. There will be no order change in paths returned by the related methods. For example: getExternalFilesDir() will list only external storage path if user formatted his SD card as "Adoptable Storage Devices". SD card path will not be available.
What happens to the files of the app when the user moves the app from/to the SD-card (using the "Adoptable Storage Devices") ? What
about the app's files on the SD-card? Would they stay? Or would they
move somewhere? For example, if the app has "file1.txt" on the
SD-card, on path "/storage/extSdCard/Android/data/appPackageName", and
it has a file "file2.txt" (or even the same name) on the primary
external storage on path
"/storage/emulated/0/Android/data/appPackageName". After switching,
what would happen for those files? How would they merge into a single
folder, if at all?
When ever user will choose his SD card as "Adoptable Storage Devices" then user need to format his SD card as internal storage using "Format as internal" option. Format means all the data/files stored on SD card will be erased. Similarly when user want to remove his SD card from "Adoptable Storage Devices" then user again have to format his SD card as portable storage using "Format as portable" option.
When moving the app to the SD-card (using "Adoptable Storage Devices"), does it mean no internal storage will be used?
Yes, original internal storage will not be used. Only SD card storage will be used because after choosing SD card as "Adoptable Storage Devices". All the data/cache will be stored to SD card
To answer your question 5: under Android 7, all files in the "public data" area, /storage/emulated/0/ (or a manufacturer-specific location; it's the directory containing DCIM Downloads, etc.), are stored either entirely in the internal memory or entirely on the adopted SD card. After the initial format of an adopted SD card the user will be presented with an opportunity to "Migrate data" which will move all of /storage/emulated/0 to the SD card. At any time the user can also go to Settings / Storage, pick the storage area that does not currently hold the public data area, and the and clicking the ⋮ (three vertical dots) icon at the upper right to bring up a menu with the "Migrate data" option.
It appears that there's no way for a user or application to force a particular public file to the SD card if an adopted card is in use; it's all or nothing. (The app's private storage will be in the internal storage or on the SD card based on whether or not the app has been moved to the SD card; there too it appears that the app will only ever be using one or the other, not both.)
I have created one app which creates one file on external memory, but when I install it on different devices the files are created in internal sdcard in some device and not created in external(Physical) sd card.
My question is that. How do we decide between the internal or external sdcard.
Which has more preference to store file by default in android?
I use the
Environment.getExternalStorageDirectory()+ "PolicyTaskfile"+"/filename.txt";
It gives external or internal sdcard path depending on the device.
The short answer is that you do not get to pick. It's up to the OEM to decide whether external storage is truly SD card or just an internal storage device (for example: eMMC). With KitKat there is a notion of primary and secondary external storage, but no easy API to determine which you are using or which is really removable media.
I've an application on the Play Store, and a user sent me a bug report saying that on his device the external sdcard is not listed in the external storage device list, though is mounted and accessible at /mnt/external_sd
I have a dialog listing folders and start directory is Environment.getExternalStorageDirectory().
After some clicks to get to the parent folder, the /storage folder is reached and getParent() returns null.
Which starting folder should I set to have access to the full storage structure?
EDIT:
As a workaround I am adding in my app preference the ability to choose if the storage root directory should be Environment.getExternalStorageDirectory() or hardcoded /mnt.
Comment/answer if there are best alternatives.
Get external storage parent folder on android
By external storage, I am assuming that you meant micro SD card storage.
external sdcard is not listed in the external storage device list,
though is mounted and accessible at /mnt/external_sd
You cannot access SD storage by using Environment.getExternalStorageDirectory() method.
Before API level 19, there was no official way to store in SD card. But, many could do it using unofficial APIs.
Officially, one method was introduced in Context class in API level 19 (Android version 4.4 - Kitkat).
File[] getExternalFilesDirs (String type)
It returns absolute paths to application-specific directories on all
shared/external storage devices where the application can place
persistent files it owns. These files are internal to the application,
and not typically visible to the user as media.
That means, it will return paths to both Micro SD card and Internal memory. Generally, second returned path would be storage path of micro SD card.
The Internal and External Storage terminology according to Google/official Android docs is quite different from what we think.
From the official documentation:
Using the External Storage
Every Android-compatible device supports a shared "external storage"
that you can use to save files. This can be a removable storage
media (such as an SD card) or an internal (non-removable)
storage ...
I'm really confused about this subject. From what I understand, using external storage doesn't necessarily mean to use a removable card, am I right? However, when talking about external storage, it's always referred as "sd card".
I'm developing an app that downloads .mp3 files from the internet. I want to save those files in the phone memory (don't want to use any removable device) but for what I have learned, those files have to be saved in external memory.However, I would like to offer the possibility of importing a file from a removable device. Where and how should I save those files?
Thanks
Difference between Internal Storage, External Storage (aka primary external storage) and Secondary External Storage?
Internal Storage: is storage that is not accessible by the user, except via installed apps (or by rooting their device). Example: data/data/app_packageName
External Storage has two types:
Primary External Storage: In built shared storage which is "accessible by the user by plugging in a USB cable and mounting it as a drive on a host computer". Example: When we say Nexus 5 32 GB.
Secondary External Storage: Removable storage. Example: SD Card.
When building an app that uses the internal storage, the Android OS creates a unique folder, which will only be accessible from the app, so no other app, or even the user, can see what's in the folder.
The external storage is more like a public storage, so for now, it's the sdcard, but could become any other type of storage (remote hard drive, or anything else).
The internal storage should only be used for application data, (preferences files and settings, sound or image media for the app to work).
If you intent to download many mp3s, i'd reccomend saving them to external storage, as the external storage is often bigger. Besides, storing data on the internal storage may prevent the user to install other applications.
The Internal and External Storage terminology according to Google/official Android docs is quite different from what we think.
According to official Android docs:-
Internal Storage: By default, files saved to the internal storage are private to your application and other applications cannot access them. When the user uninstalls your application, these files are removed/deleted. Your app user also can't access them using file manager; even after enabling "show hidden files" option in file manager. To access files in Internal Storage, you have to root your Android phone. So, this is NOT what we think as internal memory of the phone - Nexus 5's 32 GB internal memory.
External Storage:
This can be a removable storage media (such as an SD card) or an
internal (non-removable) storage
That means, both storage types like Nexus 6P's 64 GB internal memory and removable microSD card which we insert in phone's card slot are considered as External Storage.
Removable Storage means just microSD card storage, not the internal memory.
To store your app files in SD card, you may use File[] getExternalFilesDirs (String type) method in Context class. Generally, second returned path would be the storage path for microSD card (if any).
Note: I have edited - made my answer more useful after #Tunaki's comment.
From the Developer docs
All Android devices have two file storage areas: "internal" and "external" storage. These names come from the early days of Android, when most devices offered built-in non-volatile memory (internal storage), plus a removable storage medium such as a micro SD card (external storage). Some devices divide the permanent storage space into "internal" and "external" partitions, so even without a removable storage medium, there are always two storage spaces and the API behavior is the same whether the external storage is removable or not.
I think in the operating system, it defines external storage as anything not related to the actual OS filestructure. If you recall, when you write to 'internal storage', Android will make a folder privately for your application. So basically, if this is a hidden folder of some kind, it would mean that external storage could qualify as anything not being automatically hidden or managed directly by the OS. So this would mean that it would be up to the phone manufacturer about the definition of internal storage, as they could have 1 main piece of internal flash memory with two partitions on it. One partition meant to hold the os and the other meant to let you store everything on the phone.
Basically what I'm saying is: That's more a hardware related thing, and that the concept of 'external storage' could extend even to extra internal storage (flash memory) that the manufacturer added in. You could even consider storage options defined by the user as external storage as well.
Here's an updated answer for the latest Android (currently Android 13).
Internal storage used to mean the phone's internal memory and external storage used to mean, among other things, any inserted SD cards. Nowadays, this is not really the case because phones don't have SD cards any more. Phones without SD card slots still have "external storage" from the point of view of an app (eg Environment.getExternalStorageDirectory() still returns a valid location), but it's emulated - meaning it's actually a slice of internal storage.
This means one of the big differences between external and internal storage - which was that external was slower but bigger and internal fast and small - is no longer true.
Since Android 11, external storage has been scoped. This means apps get a folder of their own which is readable to them and unreadable to any other app (though see below). They can access this folder without permissions. Again, this brings external storage in line with internal. (Note scoped storage actually appeared in Android 10 but has only been enforced since Android 11).
But there are remaining differences between internal and external.
One big difference is that apps can still get a permission to read/write across all of external storage (MANAGE_EXTERNAL_STORAGE). This is hard to come by - users need to manually enable it by going into Settings, and apps which implement it are severely limited on the Play Store.
But it does mean that data written to external storage is less secure than that written to internal. Other apps may be able to eavesdrop on external.
The above is the TL;DR but there's a bit more to it. Here's a good article: https://medium.com/#tdcolvin/demystifying-internal-vs-external-storage-in-modern-android-c9c31cb8eeec