My question is related to storing files on android devices. I want to store files created in an app to an SD, if it is mounted. The problem i am having is that the device I am using has a non-removable external storage unit. All attempts to find the SD card result in finding that external storage and the files being saved there. Is there a work around, or a way to get a list of the external storage's, or way to directly save to the SD card?
Android 4.4 offers getExternalFilesDirs() (note the plural name), which may be able to give you locations on removable media like an SD card, depending upon where it is located and how the manufacturer elected to interpret Google's rules.
Everything else on Android 4.4+, in terms of removable media, cannot be written to, except presumably via apps running with superuser privileges on rooted devices.
There is no support at all for anything beyond standard external storage on Android 4.3 and below. You will find various recipes online for trying to find other partitions that might represent removable media. These recipes are not supported, may not be reliable across all devices, and will not work on many Android 4.4+ devices.
Hence, I strongly encourage you to focus on standard external storage.
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).
I was wondering, what is a good way, to prevent my app files from being read/ write to other apps, in non-root devices
Currently, I'm storing my data (images, audio, ...) in getExternalFilesDir
But, some of my users complain that, they are still able to see images in 3rd party gallery app.
I am not sure whether they are using root phone. So far, I cannot access my app getExternalFilesDir from Google Photo app.
Based on https://developer.android.com/training/data-storage, it seems that only getFilesDir will prevent other apps from accessing the files.
But, is it appropriate for an app to store user data file in getFilesDir? (My app is a note taking app which needs to store user attachment images, audio, ...)
From discussion of Android getExternalFilesDir vs getFilesDir() for big files , it seems like getFilesDir is not designed to store user data files?
I was wondering, what is a good way, to prevent my app files from being read/ write to other apps, in non-root devices
Store your data in internal storage (mostly getFilesDir() and getCacheDir()).
Currently, I'm storing my data (images, audio, ...) in getExternalFilesDir
The only reason to use that location is if you want the user to be able to use your content from outside of your app, whether via other apps or via an attached desktop computer.
In the long term, getExternalFilesDir() and getExternalCacheDir() will be off-limits to other apps — you will start seeing this on Android 11 in particular. However, it will take years for Android 11+ to dominate the Android device ecosystem.
But, some of my users complain that, they are still able to see images in 3rd party gallery app.
Such apps might be augmenting the MediaStore by scanning external storage for images.
But, is it appropriate for an app to store user data file in getFilesDir?
Yes. Everything should be in internal storage, unless there is a specific need for the user to be able to use the content outside of your app. Internal storage should be your default choice, with external storage or the Storage Access Framework being explicit choices made to go against that default.
From discussion of Android getExternalFilesDir vs getFilesDir() for big files , it seems like getFilesDir is not designed to store user data files?
Um, no.
A decade ago, internal storage and external storage were separate partitions, in part because external storage typically was implemented as removable storage (micro SD card). Since Android 3.0 in 2011, though, internal storage and external storage are almost always separate directories on the same partition. The primary distinction between the two is what processes could access the files, with your portion of internal storage being locked down to just your app, and external storage being accessible by anything.
So I'm testing an app on a galaxy s3 on 4.1 and an older phone that runs 2.3. Neither phone has an sdcard in it but when I use Environment.getExternalStorageDirectory().getAbsolutePath() on my galaxy s3 it directs me to a folder called sdcard0 within a folder called storage. When I run it on the older phone it gives me the path mnt/sdcard/ and the sdcard folder is read only.
I am trying to create a folder in these directories. I can do it on my s3 but not on my older phone.
Is there something similar to the storage folder I'm missing on the older phone or can I write to the sdcard folder when there is no sd card present?
EDIT: I have the external write permissions in my manifest
On some phones, as the documentation suggests, the word external is not to be taken all too serious:
Note: don't be confused by the word "external" here. This
directory can better be thought as media/shared storage. It is a
filesystem that can hold a relatively large amount of data and that
is shared across all applications (does not enforce permissions).
Traditionally this is an SD card, but it may also be implemented as built-in storage in a device that is distinct from the protected
internal storage and can be mounted as a filesystem on a computer.
You can check if the storage is really external or not, using the Environment.isExternalStorageRemovable()-method. If it's not removable, you should always be able to write to it (given that you have the permissions declared).
If it is however removable, you'll need to check it's current state with Environment.getExternalStorageState(). Here's a quick example of how to use it:
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
// We can read and write!
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
// Mounted read only...
} else {
// Something is wrong...
}
So in these cases, you can write to the external storage.
Important: As the documentation specifies at multiple points, the above methods work for the primary external storage. Some devices (like the Motorola Xoom) have both an internal "external" storage, and an SD-Card.
There seems to be no "generalized" way to access the "secondary external storage" on such devices, although there is a standard now, introduced with Android 4.2
Devices may contain multiple instances of external storage, but
currently only the primary external storage is exposed to developers through API.
[...]
Starting in Android 4.2, devices can support multiple users, and
external storage must meet the following constraints:
[...]
Secondary external storage must not be writable by apps.
It seems to depend on the vendor which storage (internal or real external) is considered the primary one. Not much you can do here (without things getting messy...)
If there is no external storage present, you can use your applications Internal Storage, or the caching directory, depending on what kind of data you're storing.
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.
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