Early on, Android external storage (as available via Environment.getExternalStorageDirectory()) actually stood for the physical removable card. My application goes back to 2011. When designing it back then, I made a point to place any potentially large files in the external storage, to save the precious device space.
These days, I don't have a large fleet of devices, but on all that I see the external storage is physically internal, not removable. Can't tell, though, if it's in the same filesystem as the data folder (as in Context.getDir()), i. e. are they under the shared space constraint.
Anyway, the question is - in 2019, does it still make sense to place large files into external storage as opposed to the data folder?
Anyway, the question is - in 2019, does it still make sense to place large files into external storage as opposed to the data folder?
The documentation covers why you would want to put things in internal or external storage depending on your use case:
https://developer.android.com/training/data-storage/files#InternalVsExternalStorage
Related
I'm new to Android and extremely confused about storage.
I have 4GB of internal storage on my Chromecast.
I plugged in a USB and formatted it as a storage device.
After that I enabled force push installs to external in the developer settings.
The drive name shows under the settings as USB Drive, however when I load File Commander App it's not showing at all.
When I used Termux and took a look at /mnt/sdcard/Android/obb to find a large OBB, it seems to be showing at exactly the same directory as /storage/shared/Android/obb.
So where exactly is internal storage and external storage?
How can I move files between them if I can't do so using File Commander?
In short, Internal Storage is for apps to save sensitive data to which other apps and users cannot access. However, Primary External Storage is part of built-in storage which can be accessed (for read-write) by the user and other apps but with permissions
Internal vs external storage is kind of a distinction that didn't go the way it was expected to go. I think originally it was meant to be phone storage vs SD drives, but it moved away from that. Now internal storage is special storage for an app held in phone memory. Its limited in size per app, but you should reliably be able to hold that amount. No other app can read this (unless your phone is rooted).
External storage is unlimited, but theoretically may be less reliable? You may also not be able to get any, if the device is out of space. But its not really removable anymore, so you can count on it staying there. It also is specific to your app and no other app can read it.
Then there's a few special folders in external storage anyone can access. Downloads, photos, etc. These work like external storage but data stored there can be accessed by other apps.
None of the app specific storage will show on file picker, because other apps don't have access. Unless you're rooted, in which case the rules can change. Or if you're using ADB and debugging.
As for where the actual folders are on disk- that can change depending on model. You can't depend on exact directory structure on Android. When you're writing a program that's why you use getFilesDir and getExternalFilesDir.
(If you're wondering why they still have a difference between the two- I don't know other than inertia. They've killed every difference between them, the little difference left may as well be killed to make programming simpler IMHO).
The question is how can I store a big amount of data (several hundreds of Mb and more) and simultaneously keep it available only for my application?
Internal storage as I found out is limited and its size depends on device model. Could it be sufficient for large data volume storage? Could I store 500Mb and more in internal storage?
The alternative is to use external storage. As I know, external storage doesn't limit an application and it can use the whole external storage. However, data become available for user and other applications and it is unacceptable in my case. Is there a way to make data, which stores in external storage, private as if it stores in internal one?
Internal storage as I found out is limited and its size depends on device model
Only on Android 1.x/2.x. On the vast majority of Android 3.0+ devices, internal and external storage are on the same partition and therefore have the same amount of space.
Could I store 500Mb and more in internal storage?
On Android 3.0+, probably. The user may not have 500MB free, but that's not a limitation of internal storage, but just a limitation of "storage" in general.
Is there a way to make data, which stores in external storage, private as if it stores in internal one?
Not really. You cannot prevent the user or other apps from deleting those files, for example. You can use Facebook's Conceal library to encrypt the files on external storage, with a generated encryption key stored on internal storage, to prevent users or other apps from changing the contents of the files (other than by simply corrupting them). However, again, this would only be relevant if you are still supporting Android 1.x/2.x; on Android 3.0+, just use internal storage.
considering the constrains you up you really up with two possible approaches.
use the internal storage but make sure to keep check on free memory and whenever the device can't handle it's a matter of letting your users know their device can't run your app.
use the external memory and build a nice encryption on it so even if someone else get the files, the actual data on them will be meaningless without the proper decryption mechanism.
which option to choose is a product decision.
You can use getExternalFilesDir() to restrict the media store content provider from reading your app specific files from an external storage. But I think any other application with the same permission of READ_EXTERNAL_STORAGE can access the files. Only way is to use the internal memory.
Im not sure what type of files you wish to store. If the files are less in number you can give a thought of using database, although this shall violate ACID principle. Alternatively you can think about restricting by using content providers.
My app needs to download and save a big number of images and mp3s.
These will make sense only for the app, only my app will be able to use them in an meaningful way. The user or other apps won't know what to do with them.
Where should I keep them, in external or internal storage?
I'd like to keep them in internal memory because they are only meaningful to the app, and they will be wiped out when the app is deleted.
However, for old devices the internal memory is very limited, and I think it would be a hassle for the user to keep these files here.
So, I was thinking about external memory, but I don't like the idea of keeping those files there after the app has been deleted.
What would be the best practice for this?
Thank you.
Use the path returned by 'getExternalFilesDir(String type)'
From the documentation:
"Returns the absolute path to the directory on the primary external filesystem (that is somewhere on Environment.getExternalStorageDirectory()) where the application can place persistent files it owns. These files are internal to the applications, and not typically visible to the user as media.
This is like getFilesDir() in that these files will be deleted when the application is uninstalled, however there are some important differences:
External files are not always available: they will disappear if the user mounts the external storage on a computer or removes it. See the APIs on Environment for information in the storage state.There is no security enforced with these files. For example, any application holding WRITE_EXTERNAL_STORAGE can write to these files."
For further details: http://developer.android.com/reference/android/content/Context.html#getExternalFilesDir(java.lang.String)
So yes, you can use external storage and have the files deleted when the app is uninstalled (as long as you are happy with the lack of security).
This is pretty close to an opinion question and will likely get closed.
Short answer: Use external storage. Users will get mad if you're filling up their internal storage with tons of files.
Recommendation: Give the users a toggle option to store it wherever they want!
In android, whats the difference between external storage that is nonremovable (internal) and the internal storage? I am not sure where to save my data. I just need to save a game stats that a person can pull anytime they want
Thank you
In many newer devices there will no longer be a physical distinction, with "internal" and "external" storage sharing the same flash chips without necessarily even having fixed allocation, so the difference really remains one of intended access paradigm.
Files on the external storage (real or simulated) are unavoidably shared with everything, and modifiable by anything with that manifest permission. Traditionally they are easily visible, though with the recent MTP-access devices the system may need to be told about them before a connected PC will see them.
In contrast, files on the internal storage are private to an application, excepting anything running as root or system, or if the application has decided to make them generally visible or changeable. Even when accessible, data on the internal storage can be more difficult to access outside the owning app - it's not supported by the consumer-targeted USB Mass Storage or MTP mechanisms, and even for other apps and development tools it is tricky to locate unless you know where to look, as while you may be able to examine files folders which applications have chosen to share, you cannot browse through the parent (typically /data or /data/app) folders. It can be a bit frustrating even for the developer of an app to access the files it creates on private storage during debugging (though while the apk is debuggable it is possible with the run-as tool and adb, or you can build an export capability in to the app, or run on the emulator where adb has root).
Likely your decisions process should be something like this: Is it meant to be private to the owning application? If so, put it on the internal storage, unless it's too big and targeted at older devices, in which case you may need to encrypt and/or sign it for protection before placing on the external storage. Otherwise, if it's meant to be shared, needs to be handed to arbitrary other components (email app, etc), or is big, put it on the external storage.
In android, whats the difference between external storage that is nonremovable (internal) and the internal storage?
External storage never meant removable. It always meant "accessible by the user by plugging in a USB cable and mounting it as a drive on a host computer". Early Android devices happened to have removable external storage, but that was never the definition.
Internal storage is storage that is not accessible by the user, except via installed apps (or by rooting their device).
Further to Chris' answer if you are concerned about external storage (SD card), not being avilable you can simply check this every time your app loads up and then pull in the relvent information accordingly.
You can use something like this:
if(isSDPresent)
{
// SD Card is present
// Your code goes here, files will be located # /mnt/sdcard/Android/data/packagename
}
else
{
// SD Card is not presenet
// files located here /data/data/packagename
}
If you are testing on an emulator, you can load up your DDMS and find all the files stored in the revlent places.
Hope this helps.
I am trying to decide where to store images that are sent as part of instant messages coming in to an app. These messages are viewable in a conversation history view for sometimes a significant period of time after their original receipt. You can imagine any number of other use cases that would have a similar requirement, so the question here is on the "best practice for storing an indeterminate quantity and size of images"
Assumptions
SQLite storage is clearly a bad option since the image size is not
bounded.
It is neither desirable nor undesirable that these images be publicly available to other apps or discoverable by MediaScanner. We are assumed to be perfectly neutral on this point...
This leaves two parts to this question:
1. External Storage
It seems like external storage is to be preferred when available because it is likely to have more room than anything else:
The documentation says the following:
...use getExternalCacheDir() to
open a File that represents the external storage directory where you
should save cache files. If the user uninstalls your application,
these files will be automatically deleted. However, during the life of
your application, you should manage these cache files and remove those
that aren't needed in order to preserve file space.
Unlike internal storage cache, there is no statement made about the automatic reclamation of space on external storage by Android. Still the word "cache" makes me nervous.
Question 1: Do these files remain until explicitly deleted regardless?
Question 2: Is there any other external storage other than the cache that is automatically deleted upon app uninstall AND is preferable to the external cache for some specific reason?
2. Internal Storage
Clearly not every device has external storage, so there needs to be a provision for internal storage.
Question 3: Is the only practical difference between the internal cache retrieved through getCacheDir() and files created with openFileOutput(FILENAME, Context.MODE_PRIVATE) that Android may delete files in the cache directory when under pressure for storage space?
Do these files remain until explicitly deleted regardless?
I haven't read the code, but the javadoc explicitely says
The platform does not monitor the space available in external storage, and thus will not automatically delete these files. Note that you should be managing the maximum space you will use for these anyway, just like with getCacheDir().
Is there any other external storage other than the cache that is automatically deleted upon app uninstall AND is preferable?
None that I know of.
practical difference between the internal cache retrieved through getCacheDir() and files created with openFileOutput?
It's just a facility method, AFAIK