Scoped Storage Stories: Problems with SAF
Android 10 is greatly restricting access to external storage via filesystem APIs. Instead, we need to use other APIs to work with content. This is the sixth post in a series where we will explore how to work with those alternatives, starting with the Storage Access Framework (SAF).
The Storage Access Framework is “the go-to solution” for getting access to arbitrary content on Android 10 and higher. And, since it works back to Android 4.4 (for documents) and 5.1 (for trees), it is likely to be a solution that you can apply for all versions of Android that your app supports.
However, it has a bugs and undocumented limitations.
I have filed issues about these. Unfortunately, my track record of getting anyone to pay attention to issues is not good, so all of these problems still exist.
The biggest is that device manufacturers may unilaterally eliminate the Storage
Access Framework, by removing or replacing the activities that handle ACTION_OPEN_DOCUMENT
and kin. Hopefully, manufacturers will stop doing this, as Android and its apps become more reliant
on SAF. However, since Google does not seem to test whether devices support SAF,
there is no real pressure for device manufacturers to allow SAF to function.
UPDATE 2019-12-08: the situation is complicated.
ACTION_CREATE_DOCUMENT
implies that we have write access to the location identified
by the returned Uri
. We tend to assume that ACTION_OPEN_DOCUMENT
also grants us
write access to that location. That is not a safe assumption,
as ACTION_OPEN_DOCUMENT
may return a Uri
that represents read-only content.
We have no way to request that the ACTION_OPEN_DOCUMENT
UI limit the user to read-write locations.
And while a document provider might include some hints that the Uri
it
returns points to read-only content, DocumentFile
does not support read-only content correctly.
The Storage Access Framework UI has this annoying habit of starting up in a mode that hides most of external storage. The user has to tap an item in an overflow menu to get that to show up. It turns out that there is an undocumented extra to make external storage visible in the SAF UI. However, since it is undocumented, it may be unreliable.
Among the issues filed by others, we have:
-
Due to the lack of CTS testing, not only do devices ship with intentionally-broken SAF UIs, but some devices ship with bugs in their SAF support
-
ACTION_CREATE_DOCUMENT
does not allow the user to overwrite existing content -
Google’s own Google Drive supports a subset of SAF functionality, limiting options for users and setting a poor example for other document provider implementations
With luck, some of these will get addressed eventually, though I do not have a lot of hope.
Of course, some of these problems are less with the Storage Access Framework itself and more with particular implementations of the SAF UI or of document providers. I hold out even less hope that these will ever get fixed. In many respects, this is the single biggest problem with the death of external storage: the replacement solutions involve multiple parties and multiple sources of bugs. Google needed to ensure that the SAF ecosystem was implemented properly first, and that did not happen.
The entire series of “Scoped Storage Stories” posts includes posts on:
- The basics of using the Storage Access Framework
- Getting durable access to the selected content
- Working with
DocumentFile
for individual documents - Working with document trees
- Working with
DocumentsContract
- Problems with the SAF API
- A specific problem with
listFiles()
onDocumentFile
- Storing content using
MediaStore
- Reading content from the
MediaStore
- Modifying
MediaStore
content from other apps - Limitations of
MediaStore.Downloads
- The undocumented
Documents
option - More on
RecoverableSecurityException
- How to modify more metadata in
MediaStore