Posted by Jeff Sharkey, Software Engineer, and Seb Grubb, Product Manager
Application Sandboxing is a core part of Android’s design, isolating apps from each other. In Android Q, taking the same fundamental principle from Application Sandboxing, we introduced Scoped Storage.
Since the Beta 1 release, you’ve given us a lot of valuable feedback on these changes — thank you for helping shape Android! Because of your feedback, we’ve evolved the feature during the course of Android Q Beta. In this post, we’ll share options for declaring your app’s support for Scoped Storage on Android Q devices, and best practices for questions we’ve heard from the community.
Updates to help you adopt Scoped Storage
We expect that Scoped Storage should have minimal impact to apps following current storage best practices. However, we also heard from you that Scoped Storage can be an elaborate change for some apps and you could use more time to assess the impact. Being developers ourselves, we understand you may need some additional time to ensure your app’s compatibility with this change. We want to help.
In the upcoming Beta 3 release, apps that target Android 9 Pie (API level 28) or lower will see no change, by default, to how storage works from previous Android versions. As you update your existing app to work with Scoped Storage, you’ll be able to use a new manifest attribute to enable the new behavior for your app on Android Q devices, even if your app is targeting API level 28 or lower.
The implementation details of these changes will be available with the Beta 3 release, but we wanted to share this update with you early, so you can better prepare your app for Android Q devices. Scoped Storage will be required in next year’s major platform release for all apps, independent of target SDK level, so we recommend you add support to your app well in advance. Please continue letting us know your feedback and how we can better align Scoped Storage with your app’s use cases. You can give us input through this survey, or file bugs and feature requests here.
Best practices for common feedback areas
Your feedback is incredibly valuable and has helped us shape these design decisions. We also want to take a moment to share some best practices for common questions we’ve heard:
- Storing shared media files. For apps that handle files that users expect to be sharable with other apps (such as photos) and be retained after the app has been uninstalled, use the MediaStore API. There are specific collections for common media files: Audio, Video, and Images. For other file types, you can store them in the new Downloads collection. To access files from the Downloads collection, apps must use the system picker.
- Storing app-internal files. If your app is designed to handle files not meant to be shared with other apps, store them in your package-specific directories. This helps keep files organized and limit file clutter as the OS will manage cleanup when the app is uninstalled. Calls to Context.getExternalFilesDir() will continue to work.
- Working with permissions and file ownership. For MediaStore, no permissions are necessary for apps that only access their own files. Your app will need to request permission to access media contributed by other apps. However, if your app is uninstalled and then reinstalled later, you’ll need to request permission from the user in order to be able to access media your app previously contributed.
- Working with native code or libraries. The recommended pattern is to begin your media file discovery in your Java-based or Kotlin-based code, then pass the file’s associated file descriptor into your native code.
- Working with many files efficiently. If you need to perform bulk file operations in a single transaction, consider using ContentProvider.applyBatch(). Learn more about ContentProvider batch processing here.
- Integrating with the system file picker.
- Documents apps, such as a word processor, can use the ACTION_OPEN_DOCUMENT or ACTION_GET_CONTENT action to open a system file picker. You can learn more about the differences here.
- File management apps typically work with collections of apps in a directory hierarchy. Use ACTION_OPEN_DOCUMENT_TREE to let the user pick a directory subtree. The app can further manipulate files available in the returned directory. Through this support, users can access files from any installed DocumentsProvider instance, which can be supported by any cloud-based or locally-backed storage solutions.
We’ve also provided a detailed Scoped Storage developer guide with additional information.
It’s been amazing to see the community engagement on Android Q Beta so far. As we finalize the release in the next several months, please continue testing and keep the feedback coming. Join us at Google I/O 2019 for more details on Scoped Storage and other Android Q features. We’re giving a ”What’s new on Shared Storage” talk on May 8, and you’ll be able to find the livestream and recorded video on the Google I/O site.