In this article, we will learn about Android14’s new permission that allows users to grant access to only selected media(Photos🖼️/Videos🎥), rather than the entire library.
This new permission allows users to grant partial access to media
when our app is running on Android14 or higher
New permission dialog
- It has 3 options
- You will see the new option reflects what you requested. A user will be presented with the following dialog if they request photos.
Permission dialog with new permission
The effects of declaring the new permission
By declaring
READ_MEDIA_VISUAL_USER_SELECTED, we let the permission controller know that our app supports manual re-requests to select more media.
Effects on behavior
When we declare READ_MEDIA_VISUAL_USER_SELECTED this new permission and the user
selects Select photos and videos(Select photos or Select videos)
:
- The
READ_MEDIA_IMAGES and
READ_MEDIA_VIDEO permissions are both denied 🛑
- The
READ_MEDIA_VISUAL_USER_SELECTED permission is granted ✅, providing partial and temporary access to the user’s photos and videos(photos or videos)
- Later, if we need to access additional photos and videos, we must manually request
READ_MEDIA_IMAGES
orREAD_MEDIA_VIDEO
permissions (or both).
It’s time to see how it’s implemented
- Add the following permissions to the AndroidManifest.xml
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> // new permisison <uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />
- Request permissions using ActivityResultContract
We need to request it with
READ_MEDIA_IMAGES
, READ_MEDIA_VIDEO , so that’s why we useRequestMultiplePermissions
val permissionLauncher = rememberLauncherForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { mapResults -> mapResults.forEach { Log.d(TAG, "Permission: ${it.key} Status: ${it.value}") } // check if any of the requested permissions is granted or not if (mapResults.values.any { it }) { // query the content resolver queryContentResolver(context) { listOfImages -> imageDataModelList = listOfImages } } }
- Launch permissions request flow
OutlinedButton(onClick = { permissionLauncher.launch(arrayOf(READ_MEDIA_IMAGES, READ_MEDIA_VISUAL_USER_SELECTED)) }) { Text("Allow to read all or select images") }