MediaStore Modifications
In addition to the Storage Access Framework, Google has been pushing developers towards MediaStore
more. In Android 10, that became fairly important, due to the restrictions placed on external and removable storage. Android 11 changes things again, mostly improving Android’s behavior in some key areas related to MediaStore
.
Recapping What We Got in Android 10
As we did with storage, let’s first review what changed in Android 10, as some developers are still coming to grips with those changes.
MediaStore
in Android 10 in the "Using MediaStore" chapter of Elements of Android Q!
Limited Access
The big thing is that, by default, you have limited access to the contents of MediaStore
. Specifically, by default, you can only see the content that your app has added to the MediaStore
.
To be able to query and retrieve content created by other apps, you need to hold READ_EXTERNAL_STORAGE
. Even then, you lost access to some things:
- Location metadata for images is redacted, with workarounds to get that metadata if the user permits.
- The oft-reviled
DATA
column is deprecated. It was never reliable, and it is even less reliable now.
RecoverableSecurityException
If you want to modify content from other apps, that can be done, albeit with a somewhat cumbersome process… one that becomes seriously cumbersome if you are trying to modify lots of content at once.
Your calls on ContentResolver
that would require write access — such as delete()
or openOutputStream()
— may now throw a RecoverableSecurityException
. This indicates that you do not have write access to that content, but you could get it via the exception. Specifically, that exception has a getUserAction()
method, one that returns a RemoteAction
. That has a getActionIntent()
method that returns a PendingIntent
. You can use that PendingIntent
to display a system dialog that asks the user if it is OK for you to have write access to this piece of content. If the user agrees, you can re-try your ContentResolver
call, and it should succeed.
However, this only works on an individual basis. If you try to delete()
a piece of content using its Uri
, that may give you the RecoverableSecurityException
that you need. If, instead, you use delete()
with a collection Uri
and a WHERE
clause, that will simply fail. In Android 10, there is no bulk option, where you can request write access to a list of Uri
values or an entire collection.
Also, not everything is writable, even with this per-content permission. For example, you can update the TAGS
column for an image, but not the DESCRIPTION
.
See this blog post from the author of this book for more about RecoverableSecurityException
.
New Collections
Two new MediaStore
collections appeared… though only one was documented.
The documented one was MediaStore.Downloads
, to access the content of the Download/
directory. The undocumented one was one for the Documents/
directory, which requires a convoluted means to access.
Both of these are restricted more than the other collections. In particular, you can only see your own app’s content, even with READ_EXTERNAL_STORAGE
.
Prev Table of Contents Next
This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.