Implementing Photo Picker on Android + Kotlin + Jetpack Compose

Android’s new(ish) Photo Picker is a secure, straightforward way of allowing users to pick photos and/or videos from their library. This article explains its benefits and shows how to use it with Kotlin + Compose.
Here’s the GitHub link for the code in this article: https://github.com/tdcolvin/PhotoPickerDemo

Why is Photo Picker secure?
Because the app only gets access to the photos that the user has selected.
In the old days, if you wanted to show the user a list of their photos so they could select one, your app had to request access to the user’s entire photo library. This opened the door to malware that could grab all your photos without you knowing it. With Photo Picker, no such wide permission is required.
In fact, no permissions are needed to use Photo Picker at all. This is perfectly safe, since the user already has complete control over which photos are made available to the app.
How do you use it?
The Photo Picker is fairly easy to use, but the official docs are stuck in Activity-land rather than using Compose. So here’s how it’s done the more modern way.
Launching the Photo Picker
This is done via a startActivityForResult()
. That’s easily done with Activities, but using Compose we need a little help from AndroidX. Add this to your module’s Gradle file if it isn’t there already:
//For rememberLauncherForActivityResult()
implementation 'androidx.activity:activity-compose:1.6.1'
//For PickVisualMedia contract
implementation 'androidx.activity:activity-ktx:1.6.1'
That gives us access to rememberLauncherForActivityResult()
, which is the Compose way of launching an activity and waiting for it to provide a result, and to PickVisualMedia
, which is the contract needed to open the Photo Picker.
Putting it all together:
Note that PickVisualMedia
forces the user to choose a single photo — if you want to allow multiple, then use PickMultipleVisualMedia
instead.
In either case, this creates a launcher which we can use to open the photo picker. It doesn’t open it by itself: instead, we launch()
that launcher with a PickVisualMediaRequest
argument describing the type of media allowed. Options are:
mediaType = ActivityResultContracts.PickVisualMedia.ImageOnly
to show only imagesmediaType = ActivityResultContracts.PickVisualMedia.VideoOnly
to show only videomediaType = ActivityResultContracts.PickVisualMedia.ImageAndVideo
to show both images and video
Here’s how that launcher is launched, in this case as the result of a button press:
The result is returned through the launcher created above. It’s returned as a URI which can be used to access the file directly.
In the sample app, I create a by remember()
variable to save the URI to:
And finally, to display the image on the screen I use the Coil library’s rememberAsyncImagePainter()
function:
To use the Coil library, add it to your module’s Gradle file as so:
//for rememberImagePainter and image loading functionality
implementation("io.coil-kt:coil-compose:2.2.2")
The result
On Android 13, the photo picker works perfectly:

On older versions of Android where Photo Picker isn’t available, the Intent fired falls back to the document selector. This is the behaviour on Android 7:

This is a graceful fallback. Whilst the UX isn’t quite as crisp as the Photo Picker, it’s still usable — and crucially, it still doesn’t require permissions on your whole photo library.
So where is Photo Picker supported?
Photo Picker was released in Android 13, but it’s also supported on Android 11 and above if the latest modular system updates have been installed via Google Play. This is the case for most Android 11+ users.
There is much talk of this having been added to Play Services, too, which would enable support all the way down to Android 4.4. It was shown as having been included in the Play Services update of November 2022. But, so far, there have been no official instructions on its use. We can poke around and surmise what might be needed (Mishaal Rahman’s research found the specific Intent required, for example), but even if it did work it’s worth waiting until officially documented to prevent unexpected twists.
So there we have it. A straightforward, secure way of picking photos or videos which does work with Kotlin + Compose.
Here’s the GitHub link for the code in this article: https://github.com/tdcolvin/PhotoPickerDemo
Tom Colvin is CTO of Apptaura, the app development specialists; and Conseal Security, the mobile app security testing experts. Get in touch if I can help with any mobile security or development projects!