Scoped Storage on Android 11

Fernando García Álvarez
ProAndroidDev
Published in
4 min readFeb 20, 2020
Source: Google

This is a follow-up to my previous post about Scoped Storage, so I highly recommend reading that one first since this post will build upon that foundation.

On February 19th, the first Developer Preview of Android 11 was released and it introduces changes to Scoped Storage, adding new features and fixing some annoyances.

What is Scoped Storage?

Scoped Storage prevents apps from having unrestricted access to the filesystem on the device. Previously, an app could access any file on the device using the standard File APIs, and it only needed the user to grant the storage permission.

If you update your app to target API 29 without making any changes, and you are accessing files using the standard File APIs, you’ll find those calls no longer work. Instead, you have to rely on the Storage Access Framework (SAF) in order to open files or folders, and if you are displaying media items from the MediaStore, you have to work exclusively with Uris, not file paths (also, in order to delete or overwrite media items you have to ask the user for permission to modify those specific files, simply requesting the WRITE_EXTERNAL_STORAGE permission no longer works).

Is Scoped Storage required for all apps on Android 11?

When Android 10 was released, Google hinted at Android 11 requiring all apps to use Scoped Storage, regardless of targetSdkVersion.

However, now Google has given developers more time to make the migration, so it’ll only be required when your app targets Android 11 (remember that by the end of 2021 all the new apps and updates to existing apps on the Google Play Store must target Android 11).

If your app doesn’t target Android 11 yet, you can temporarily opt out of Scoped Storage by setting android:requestLegacyExternalStorage=”true" on the application tag inside of AndroidManifest.xml, just like on Android 10. However, one difference between Android 10 and 11 is that on Android 11 as soon as your app targets Android 11, you lose the ability to opt-out of Scoped Storage (on Android 10 it was still possible).

Batch operations

As discussed in my previous post, on Android 10 Scoped Storage didn’t allow for easy batch operations that modify existing media items (for example, overwriting or deleting a group of photos). Instead, you were limited to either showing a permission dialog for each media item (which is not very user-friendly if you are working with many files at once), or having to convert the media Uri to a SAF (Storage Access Framework) Uri and working with the file using SAF operations (with the unfortunate consequence of having to first request access to the entire folder, which is not ideal).

Batch deleting

Imagine you need to delete two photos. Now, on Android 11, you can request permission for the two photos at the same time by simply calling MediaStore.createDeleteRequestand passing the Uris of the MediaStore items you want to delete, like so:

Batch delete image request

You might have noticed that in the above code first, we are checking if we have permission to write to any of these Uris. This step is completely optional, but if you don’t do this, then the permission prompt will request access for all of them, including those for which you already hold write access.

The previous code produces a single permission prompt for all images, as shown below:

Batch delete permission dialog

There are also two other methods that work similarly, MediaStore.createFavoriteRequestand MediaStore.createTrashRequest, in order to mark a media item as favorite and to mark it as trash, respectively.

Batch overwriting

The process of requesting permission for batch overwriting is very similar to batch deleting, shown above. We need to call MediaStore.createWriteRequestinstead.

Overwrite images request

One important thing to note in this case is that the permissions granted are tied to the lifecycle of the Activity that requested them, and in this case also we can’t request a persistable permission.

For this reason, if we need to perform some long-running operations with the data outside of the Activity, we need to place items (Uri) into Intent’s data field or into a ClipData, like so:

Passing permission to service

Other new additions

One of the new additions of Android 11 is the so-called “All Files Access”, designed for apps that need broad file access, like file managers. Apps have to declare the MANAGE_EXTERNAL_STORAGEpermission and direct users to a system settings page where they can enable the option to allow access to manage all files for the app, which allows apps to read and write to all files within shared storage and access the contents of MediaStore.Files.

Also, now apps that have the READ_EXTERNAL_STORAGEpermission can read a device’s media files using direct file paths and native libraries, which helps avoid problems while using third-party libraries.

Conclusion

Although the basic idea and interactions of Scoped Storage, as mentioned in my previous post, remain untouched, Android 11 addresses common pain points with useful APIs.

I hope this post helps you while modifying your app to use Scoped Storage.

You can contact me on Twitter @fergaral96

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Published in ProAndroidDev

The latest posts from Android Professionals and Google Developer Experts.

Responses (1)

What are your thoughts?