Blog Infos
Author
Published
Topics
Published

Have you ever had a requirement where users can select photos or videos from their gallery, well in order to support such kind of functionality it was important to ask permission from the user to access media files.

What’s changing now?
A permission-less approach to select media files where the app will only have access to those images which user is selecting instead of getting access to all the media files (images/videos)

PickVisualMedia
When you want the user to select a single media file then you may use the PickVisualMedia, it will return the Uri that you can use later on to display that media on screen.

Let’s see the codebase with respect to Jetpack Compose by adding such capability through the composable

val mediaPicker = rememberLauncherForActivityResult(
    contract = ActivityResultContracts.PickVisualMedia(),
    onResult = { uri ->
        imageUri = uri
    })

Use the Activity Result API to define the contract as ActivityResultContracts.PickVisualMedia(), once user select the media you will get the uri in onResult lambda

The next step is to convert URI to bitmap, this is purely optional you can even use URI with coil library.

//This logic is only for image not for video
LaunchedEffect(key1 = imageUri) {
    imageUri?.let { uri ->
        bitmap = if (Build.VERSION.SDK_INT < 28) {
            MediaStore.Images
                .Media.getBitmap(localContext.contentResolver,uri)
        } else {
            val source = ImageDecoder
                .createSource(localContext.contentResolver,uri)
            ImageDecoder.decodeBitmap(source)
        }
    }
}

Finally to show the selected image you may set the bitmap to Image composable.

Image(bitmap = bitmap.asImageBitmap(), contentDescription = "Selected image")

Here bitmap is a nullable mutable state object like below
var bitmap by remember mutableStateOf<Bitmap?>(null) }

Now the final question is how to start the experience so that user can select images or videos from the gallery.

On a button click you may use the object defined using the Activity Result API for us its “mediaPicker” and call the launch() method.

Select only Image

Button(onClick = {
    mediaPicker
      .launch(PickVisualMediaRequest(
          ActivityResultContracts.PickVisualMedia.ImageOnly
       )
    )}
) {
    Text(text = "Pick image only")
}

Select only video

Button(onClick = {
    mediaPicker
      .launch(PickVisualMediaRequest(
          ActivityResultContracts.PickVisualMedia.VideoOnly
      )
 )}
) {
    Text(text = "Pick video only")
}

Select an image or video

Button(onClick = {
    mediaPicker
        .launch(PickVisualMediaRequest(
            ActivityResultContracts.PickVisualMedia.ImageAndVideo
        )
    )}
) {
    Text(text = "Pick image or video")
}

 

Job Offers

Job Offers

There are currently no vacancies.

OUR VIDEO RECOMMENDATION

, ,

From Scoped Storage to Photo Picker: Everything to know about Storage

Persistence is a core element of every mobile app. Android provides different APIs to access or expose files with different tradeoffs.
Watch Video

From Scoped Storage to Photo Picker: Everything to know about Storage

Yacine Rezgui
Android developer advocate
Google

From Scoped Storage to Photo Picker: Everything to know about Storage

Yacine Rezgui
Android developer ad ...
Google

From Scoped Storage to Photo Picker: Everything to know about Storage

Yacine Rezgui
Android developer advocat ...
Google

Jobs

In a similar way when you want users to select multiple images or videos then instead of “ActivityResultContracts.PickVisualMedia()” you may use “PickMultipleVisualMedia()”

val mediaPicker = rememberLauncherForActivityResult(
    contract = ActivityResultContracts.PickMultipleVisualMedia(),
    onResult = { uriList ->
        //handle list of Uris
    })

With ActivityX 1.7.0 release, the Photo Picker support library will use a back-ported version provided by Google Play services on devices running Android KitKat (4.4) and later.

To enable back-ported photo picker, add the following service to the Manifest file

<service android:name="com.google.android.gms.metadata.ModuleDependencies"
    android:enabled="false"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.android.gms.metadata.MODULE_DEPENDENCIES" />
    </intent-filter>

    <meta-data android:name="photopicker_activity:0:required" android:value="" />
</service>

That’s it, with those little steps, you have added support for picking media files from the gallery without explicitly asking for permission.

This article was previously published on proandroiddev.com

YOU MAY BE INTERESTED IN

YOU MAY BE INTERESTED IN

blog
Android 13 (API 33) introduces a new tool called photo picker 🖼. Today, we…
READ MORE
blog
Google recently announced the first Developer Preview of Android 13, while there are a…
READ MORE
Menu