How Google is backporting Android 13’s Photo Picker
In case you haven’t heard already, the release of Android 13 is right around the corner. Out of the many, many new features it introduces, one of the most important additions highlighted by Google themselves is the new Photo Picker. This feature, as its name suggests, lets the user select photos (or videos) to insert into another app. Android already has this capability, but the Photo Picker has a better UI and does things in a more privacy-friendly way.
Unlike many of the other new features introduced with Android 13, the Photo Picker isn’t tied to anything new added in the update itself. Because it uses existing platform capabilities and is included in one of Android’s modular system components, the new Photo Picker can be backported to versions of Android as far back as Android 11. In fact, Google already rolled out the feature to all devices running Android 11+ through a Google Play System Update. You may not see the feature in action for a while, though, as apps need to be updated to support it.
If you’re running an even older version of Android, like, say, Android 9, then there’s a chance you’ll get access to the new Photo Picker as well. That’s because Google is working on a backward compatible version of the Photo Picker feature, one that they may deploy soon if everything goes as planned.
In this edition of Android Dessert Bites, I’m diving into Android’s new Photo Picker feature to explain how it works and how it’s delivered to users.
(Although most of us first heard about it from the Android 13 Developer Preview 1 announcement, Google actually first announced the Photo Picker at last year’s Android Dev Summit.)
Why the Android Photo Picker even exists
When you want to share a photo or video with an app, that app needs two things: the location of those files and the permission to access them. This is true for every app that interacts with media files on your device, whether it be a gallery app, a social media app, or a messaging app. Many apps that need to access photos or videos don’t need persistent access to them or access to other types of files. Your favorite social media app, for example, shouldn’t need to access every single photo or video stored on your device at any time they want. Instead, apps like these should only access photos or videos explicitly chosen by the user, and only when they’re actually going to do something with them (like composing a new tweet).
That’s the idea behind the new Photo Picker in Android. Apps that need to access photos or videos can call the Photo Picker to let the user choose which photos or videos to share. The app then has temporary, read-only access to those files. When the app’s process ends, it loses access to those files.
Thanks to the Photo Picker’s clean UI, users can quickly share media files between apps, and they can do so without having to worry about granting access to their entire photo and video library in the process. This was a big problem before Scoped Storage came about and this new feature can be considered an extension of Google’s efforts to reduce how many apps have broad access to files on shared storage.
For app developers, meanwhile, the feature reduces friction by removing the need to request any permissions. Android considers media files sensitive data, especially image files as they may contain location metadata. That’s why Android places roadblocks in the form of different permissions that apps need to hold in order to read any media file they don’t own on demand, read the location metadata of image files, or read every file on shared storage. Every permission grant is another hurdle that could put a user off from using an app, so only apps that really need these capabilities should consider requesting them. Reducing the number of apps that hold sensitive permissions without limiting functionality or burdening users with excessive dialog boxes is a difficult balance to maintain, but Google manages to thread the needle with every release.
That’s why the Photo Picker is a win-win for both users and developers, and it’s why Google is encouraging developers to adopt it when possible and is rolling it out to as many users as they can. But where does the Photo Picker pull files from, and how do apps actually interact with it?
How the Android Photo Picker actually works
Since media files can be scattered across directories on shared storage, the Android framework provides something called the media store, which is an optimized index into media collections. Apps can contribute media files to one or more of Android’s media store collections, including MediaStore.Images, MediaStore.Video, MediaStore.Audio, MediaStore.Downloads, and MediaStore.Files. The MediaStore.Images table, for instance, includes photos, screenshots, and other image files stored under the DCIM/ and Pictures/ directories on shared storage. The MediaStore.Video table, meanwhile, includes video files stored in DCIM/ and Pictures/ as well as Movies/. The Photo Picker pulls photos and videos indexed in these two tables and shows them to the user in the picker activity.
At a high level, apps call the Photo Picker by sending the MediaStore.ACTION_PICK_IMAGES intent. The picker then pops up, and the user selects one or more files to share with the app. The picker then returns the MediaStore content URI(s) of the files that were picked. These uniform resource identifiers can be used to read the file or data about the file. The URIs that are returned by the picker are specifically called “picker” URIs because they can only expose a limited set of read-only operations, such as reading the file and querying when it was taken, what its name is, how big it is, etc.
The activity that responds to the ACTION_PICK_IMAGES intent, ie. the Photo Picker itself, is contained within the MediaProvider system app. MediaProvider is what’s responsible for the media store, and it was turned into a modular system component (ie. a Project Mainline module) that all OEMs had to preload on their GMS Android devices starting in Android 11 (though excluding Android Go Edition devices). That’s what makes it updatable via the Play Store, and it explains how Google managed to bring the Photo Picker to devices running Android 11-12 with the May 2022 Google Play System Update.
As I mentioned at the beginning, Android already has the capability of letting users select photos or videos to share with apps. However, this was previously handled by the DocumentsUI system app (the “documents picker”), which has been in Android since Android 4.4 KitKat. Apps can send the ACTION_GET_CONTENT or ACTION_OPEN_DOCUMENT intent to launch the documents picker so the user can pick one or more files to share. Apps can optionally specify EXTRA_LOCAL_ONLY in the intent to make the documents picker only show files stored locally, and they can also specify the MIME type so the documents picker will initially show files of a particular type. In terms of pure functionality, the documents picker is superior, but in terms of UI, it’s less intuitive to use.
The Photo Picker not only has a cleaner UI than the documents picker, but as I mentioned before, it also provides apps temporary, read-only access to user-selected photos and videos. In contrast, apps that interact with the system documents picker through ACTION_OPEN_DOCUMENT have the ability to edit those files.
The Photo Picker is undoubtedly a great feature, and it’s already available on every Android 11+ device with the May 2022 or newer Google Play System Update. But you probably haven’t seen it in action yet, and there are reasons for that.
How do you use it?
Google made the Photo Picker APIs public a couple of months ago, but in order to use them, an app needs to be compiled against API level 33, the API level for Android 13, by setting the compileSdkVersion to 33. Since Android 13 only recently reached Platform Stability, though, the vast majority of apps have yet to take this step. (Since the Photo Picker interaction involves a normal intent, though, apps can likely just craft the intent directly instead of through the API, send it out, and then read the response, bypassing the need to change the compileSdkVersion.)
Developers also need to know if the feature is actually available for a particular device before using it. You can assume it’s available on all devices running Android 13, but you can’t make the same assumption about devices running Android 11-12. Since the feature is only available on Android 11-12 devices with a Google Play System Update version of May 2022 or newer, apps could in theory query the Google Play System Update version…but there’s no publicly documented method to do so. (The Settings app uses PackageManager’s getPackageInfo method to read the version name of the ModuleMetadata app, which is how it knows what the Google Play System Update version is.)
Developers should not hardcode their apps to only use the new Photo Picker on Android 13 and above devices. What apps should do instead is to read the extension SDK level of the device using the SDK Extensions API. SDK Extensions is a Project Mainline module that’s responsible for deriving the extension SDK level and providing APIs for apps to query it. Why does Android have an extension SDK level and a regular SDK level? Well, it’s because of what Project Mainline did to Android.
Most new Android APIs are introduced through updates to the entire Android OS framework. When an Android version reaches Platform Stability, the API surface is frozen and can’t be added to or modified. Developers building an app targeting a certain API level can be sure that those APIs are stable, ie. they can’t suddenly change until the next OS update.
However, Project Mainline changes this calculus. With Mainline, new APIs can be added outside of OS updates, such as what happened with the Photo Picker. There’s an extension SDK level for each Android platform version that is increased as new APIs are added, and the SDK Extensions API lets apps determine at runtime whether or not those new APIs are available on a device. Photo Picker, for instance, is only available on Android 11 and Android 12 devices with extension SDK levels of 2 or greater, so apps looking to use it on Android 11-12 need to be aware of this.
Alternatively, developers could simply query whether any apps can handle the Photo Picker intent. That’ll work in this particular instance since the API involves intents, but it won’t work for every new API added through Mainline updates.
Instead of dealing with any of these considerations, though, most developers are probably better off integrating libraries like ModernStorage that simplify storage interactions. The modernstorage-photopicker library, for example, was made specifically to deal with sending the Photo Picker intent when the feature’s available or to fall back to ACTION_OPEN_DOCUMENT when it’s not. The androidx.activity library also checks if the Photo Picker is available on Android 11-12, and if not, falls back to the ACTION_OPEN_DOCUMENT intent that’s available on Android 4.4+.
The more developers that are aware of how to use the Photo Picker feature on Android 11-12, the faster this feature will start being deployed in all your favorite apps. If you’d like your favorite app to use the feature, send its developer a link to this article! If Google goes through with its plan to backport the feature to even older versions of Android, as I’ll explain below, then developers will have even more of an incentive to support it.
Google may backport the feature to Android 10 and older versions
In the list of Google System Updates for July 2022, Google said the version v22.30 of Play Services adds a feature that “allows applications to ask users for temporary, read-only access to one or more user-selected photos or videos. This is a backward compatible version of a feature available in Google Android version 11 (R, API 30) or higher.” The description of the feature is vague but closely matches what we know about the Photo Picker.
Following this lead, I analyzed the Manifest of a publicly available Google Play Services v22.30.14 APK targeting API level 28 (ie. Android 9) and found that it added a new activity with the same name and icon as the activity that’s provided on Android 11+ devices through the MediaProvider app. In other words, Google Play Services is adding its own Photo Picker. Play Services’ activity doesn’t filter for the exact same activity action as MediaProvider’s, but they’re quite similar (
com.google.android.gms.provider.action.PICK_IMAGES for Play Services versus
android.provider.action.PICK_IMAGES for MediaProvider).
I haven’t been able to activate the Photo Picker in Play Services yet, but given this finding as well as what was mentioned in the Google System Updates page, I’m confident that Google is at least exploring the idea of backporting the feature to even older versions of Android than previously thought. Google did remove the line about this feature from the Google System Updates page a few days after they added it, though, so it’s possible these plans have been scrapped or the Play Services version of the feature just isn’t ready yet. If I find out either way, I’ll be sure to update this article and mention it on Twitter.
What’s next for the Photo Picker?
The Photo Picker currently only shows photos and/or videos stored locally on the device, but that’s only because apps have to be updated to use the CloudMediaProvider API. Apps can create a cloud media provider that offers read-only access to media files stored in a cloud storage service. For example, Google announced at I/O 2022 that it will update its Photos app to act as a cloud media provider, letting users access backed-up photos and videos as well as custom albums through the Photo Picker.
In a future update to MediaProvider, there will be a settings page to “change the enabled CloudMediaProvider on the device and other media selection configurations.” This settings page doesn’t exist yet, but its existence is confirmed from the documentation for the ACTION_PICK_IMAGES_SETTINGS intent.
Thanks for reading this edition of Android Dessert Bites! If you want to learn more about this column as well as read previous editions, you can find them here.