Apps usually don't write data to external SD card, but starting with Android 4.4 up to latest release 10, there is no permission to stop apps writing to Android
directory on external storage. The reason is more historical than technical.
ANDROID'S STORAGE JOURNEY:
Android provides two types of storage to apps: private (or internal) and shared (or external). As names suggest, private directories of every app (in /data/data/
) aren't accessible to other apps, but data placed on shared storage is.
External storage used to be physically external SD card (with permission-less filesystem from FAT family) in early days when flash storage was costly. So apps used to place a lot of data on external SD card.
Android enforced WRITE_EXTERNAL_STORAGE permission as early as in Android 1.5 to control which apps could write to external storage, so almost every app had to request this permission.
As the internal flash memory grew in size, OEMs created a separate partition (usually named sdcard
) "to provide external storage internally". Now there were two external storage: primary (sdcard
partition) and secondary (external SD card). Since primary external storage was still smaller, apps continued to widely use secondary storage by placing files wherever they wanted, creating random directories on both storage.
In Android 2.3 FUSE was introduced to emulate primary external storage (/sdcard
) over actual filesystem of sdcard
partition which majorly remained vFAT. But the primary intention was to retain a permission-less virtual filesystem (like FAT) over a permission-aware Linux filesystem (like ext4
) so that data could be shared among apps (UIDs).
Android 3.1 switched USB Mass Storage (UMS) to Media Transfer Protocol (MTP). It means that sdcard
partition or external SD card was not mounted as partition when connected to PC. So actual filesystem contents aren't visible over MTP, instead MediaStore (one of Android's built-in content providers) provides an indexed list of files. Also apps can make use of this content provider. See details in this answer.
Starting with Android 3.2 apps write-ability to external SD card was restricted to only system apps (using WRITE_MEDIA_STORAGE
permission). See details in How to move files to external SD card?. On rooted devices this restriction is hacked by mapping GID media_rw (1023)
to WRITE_EXTERNAL_SRORAGE permission.
By the release of Android 4.0 (started with 3.0) OEMs started emulating /data/media
on /sdcard
as primary external storage, which eliminated sdcard
partition. This was not possibly with UMS because /data
could not be un-mounted from Android to mount on PC. This is true to till date.
Android 4.3 merged multiple fstab
s used previously to a single /fstab.<device>
file and introduced voldmanaged
flag for external filesystems to be mounted by vold
. With Treble support in Android 8, fstab
was moved to vendor
partition and in DTB. See What is default “fstab” file in Android?
In Android 4.4 making use of FUSE-based synthesized permissions, apps were allowed to write to their "private directories" (inside Android/{data,media,obb}/
directories) on "shared storage" without requesting Storage permission. It made it officially possible for apps to use multiple external storage (primary and secondary). Also READ|WRITE_EXTERNAL_STORAGE
was necessarily required to read external storage, including other apps' private directories.
Storage Access Framework (SAF) was introduced to let non-system apps write to SD card and direct write access to secondary external storage was strictly stopped. So now it was made clear that external storage is not always removable storage, the former could be physically internal. Transient storage like USB is in addition to these.
Coming to your question:
I'd prefer that all the application data is on the internal storage rather than on the SD card.
Third party apps cannot write directly to public directories on secondary external storage, but cannot be stopped from writing to their private directories (1, 2, 3, 4), thanks to synthesized permissions based on directory structure:
"The WRITE_EXTERNAL_STORAGE
permission must only grant write access to the primary external storage on a device. Apps must not be allowed to write to secondary external storage devices, except in their package-specific directories as allowed by synthesized permissions. Restricting writes in this way ensures the system can clean up files when applications are uninstalled."
And:
"Starting in Android 4.4, the owner, group and modes of files on external storage devices are now synthesized based on directory structure. This enables apps to manage their package-specific directories on external storage without requiring they hold the broad WRITE_EXTERNAL_STORAGE
permission. For example, the app with package name com.example.foo
can now freely access Android/data/com.example.foo/
on external storage devices with no permissions. These synthesized permissions are accomplished by wrapping raw storage devices in a FUSE daemon."
By accessing / creating their private directories, apps confirm if the secondary external storage is available. So in most cases the directories under Android
directory on SD card are either empty, or the files are a copy of those on primary external storage. Though it doesn't make sense most of the times, but some app developers may prefer to save data on secondary external storage, it's up to their will. E.g. for quickly expanding raw video files or large OBB files as mentioned by Andrew in comment. Android's suggestion:
"... the device has two different external storage directories, so you need to select which one to use when writing "private" files to the external storage.
...
The first entry ... is ... the primary external storage, and you should use that location unless it's full or unavailable."
And the other one:
"An application may store data on any or all of the returned devices. For example, an app may choose to store large files on the device with the most available space"
Since private directories on external as well as internal storage are deleted on app uninstall, the preferred storage for apps to store persistent data (like photos) is primary external public storage. This norm continues to till date. Therefore it's usually safe to delete Android
and other empty directories (some Android versions also create standard directories) on external SD card but those would be recreated.
STORAGE JOURNEY CONTINUED...
SAF (file picker) was extended in Android 5 (for Directory Selection) and then in 7 (to Scoped Directory Access). Android 10 further extended it to Scoped External Storage Access entirely removing filesystem level access to primary external storage as well, replacing with filesystem APIs.
Android 6 introduced Adoptable Storage to use SD card as primary external storage by encrypting it (vold
flag in fstab
: encryptable=userdata
). Now even apps and their data on internal storage can be moved to adoptable storage. See How to move apps from internal to external storage? This was previously achieved by OEMs and custom ROM developers by applying patches like "Default write disk" or "Disable Internal Memory" to AOSP. Apps like "Link2SD" also filled the gap on rooted devices.
Additionally Storage Configuration (storage.xml
) was removed from framework-res.apk
and merged to fstab
. UUID based mount path was introduced.
Also many install-time permissions were shifted to runtime permissions and in order to make WRITE_EXTERNAL_STORAGE
a runtime permission, mount namespaces were used. For details see What is the “u#_everybody” UID? and What is /storage/emulated/0/?
FUSE was removed completely in Android 9. sdcardfs
is now used for emulation. Read full story here.