The Storage Situation: Removable Storage
Back in 2014, I wrote a series of blog posts to try to clear up confusion
around where you can read and write files in Android. I updated them in
2017 to reflect changes in Android��� but Android keeps changing.
This post is an updated
edition of the 2017 post on removable storage.
Working with files on the filesystem in Android is seriously confusing.
It was confusing in 2008, and it has only gotten more confusing as the years
rolled on. There
are countless Stack Overflow questions and the like where they clearly do not
quite grok the various pieces of Android���s storage model.
This is the third post in a series covering this storage model, to help
clarify what is going on. Earlier, we looked at
internal storage and
external storage.
Today, we will look at removable storage, the source
of an unfortunate amount of angst.
What Your Users Think ���Removable Storage��� Means
Many of your users will have a device that has some sort of removable media.
Often times this is a micro SD card. Some tablets or docks have a full SD card slot.
Plus, USB mass storage is possible via USB On-The-Go and USB Type C connectors (not to mention
devices or docks with a full USB host port).
Your users will think that they can work with removable storage much like they
can with a desktop or notebook.
Unfortunately, your users are largely mistaken, and are even more mistaken
with Android 4.4+. That���s because Google���s approach towards removable storage is���
unconventional.
What Google Thinks ���Removable Storage��� Means
In the beginning, external storage was often in the form
of a removable micro SD card. At that time, many developers got in the habit of
thinking that external storage == removable storage.
However, as Android 3.0 and higher started rolling out en masse, developers soon
started to realize two things:
External storage != removable storage on most of those devices
There���s nothing in the Android SDK for removable storage
Wait, Wut?
That���s right: until Android 4.4, there was no official support for removable media
in Android. Quoting Dianne Hackborn:
���keep in mind: until Android 4.4, the official Android platform has not supported SD cards at all except for two special cases: the old school storage layout where external storage is an SD card (which is still supported by the platform today), and a small feature added to Android 3.0 where it would scan additional SD cards and add them to the media provider and give apps read-only access to their files (which is also still supported in the platform today).
Android 4.4 is the first release of the platform that has actually allowed applications to use SD cards for storage. Any access to them prior to that was through private, unsupported APIs. We now have a quite rich API in the platform that allows applications to make use of SD cards in a supported way, in better ways than they have been able to before: they can make free use of their app-specific storage area without requiring any permissions in the app, and can access any other files on the SD card as long as they go through the file picker, again without needing any special permissions.
But��� But��� But��� What About All These Apps That Used Removable Media?
They fall into three buckets:
Some are just relying on MediaStore indexing. So, for example, a video player can
find out about videos on all available media by querying the MediaStore, and if
the device manufacturer hasn���t broken the MediaStore indexing of removable media,
the player will be able to play back videos on removable media. This strategy is
broken on Android 10 and higher.
Some are apps that ship with the hardware. The hardware manufacturer knows the
device and what the rules of the game are for that device. The hardware manufacturer
is also far less concerned about cross-device compatibility, as their apps aren���t
(usually) shipping on the Play Store. Hence, a hardware manufacturer has carte blanche
to work with removable media.
Some are apps written by developers who decided to go past the boundaries of
the Android SDK. There are various recipes online for examining various Linux
system files (and file-like substances) to determine what ���mount points��� exist,
and from there apply some heuristics to determine what represents removable media.
While reliability across devices could easily be an issue, beyond that, these
techniques at least sorta worked��� until Android 4.4, when everything changed.
What Happened in Android 4.4
Starting with Android 4.2, there was a request from Google for device manufacturers to
lock down removable media. Generally, this was ignored.
For Android 4.4+, Google amended the Compatibility Test Suite (CTS) that device manufacturers
must comply with in order to ship a device containing Google���s proprietary apps
(e.g., Play Store, Maps, Gmail; otherwise known as ���GMS���). Quoting
Dave Smith:
However, new tests were added in CTS for 4.4 that validate whether or not secondary storage has the proper read-only permissions in non app-specific directories, presumably because of the new APIs to finally expose those paths to application developers. As soon as CTS includes these rules, OEMs have to support them to keep shipping devices with GMS (Google Play, etc.) on-board.
As a result, apps were able to read files on removable media using the various undocumented
and unsupported tricks for finding removable media. However, apps cannot write to or
otherwise modify such removable storage. Note that device manufacturers themselves
may have ways of dealing with this, but ordinary app developers do not.
However, we were given getExternalFilesDirs() and getExternalCacheDirs() in
Android 4.4. Android 5.0 added getExternalMediaDirs(). These methods give us
locations on external and removable storage into which our apps can write. We
do not need any permissions to use them ��� not even the runtime permissions from
Android 6.0. However, the filesystem locations are a bit user-hostile and the content
that we place in those directories will be removed when the app is uninstalled.
What Happened in Android 10
Removable storage, like external storage, was largely locked down. We still
have access to the locations from the aforementioned methods. However, any other
���back door��� approaches that developers used were completely shut down.
This blog post
has much more detail on what Android 10 did to external storage, and all that
also applies to removable storage.
Should I Hardcode Paths in My App?
No.
Other Posts in This Series
This series includes:
A post on internal storage
A post on external storage
This post on removable storage


