Android Version-Specific Permission Handler for Composables in Jetpack Compose

Anil Kr Mourya
3 min readOct 17, 2024

In modern Android development, managing permissions is crucial for ensuring your app functions correctly while respecting user privacy. This guide explores how to handle runtime permissions in Jetpack Compose using the PermissionHandlercomposable function.

Understanding the Need for Permissions

Android apps often require access to sensitive data and features, such as location and media. With recent Android updates, managing these permissions has become more nuanced. Here, we present a simple and effective way to request multiple permissions while providing a user-friendly interface.

Implementation of PermissionHandler

Below is thePermissionHandler function that manages permissions in your Jetpack Compose application. This function checks for necessary permissions based on the Android version and prompts the user to grant them.

@OptIn(ExperimentalPermissionsApi::class)
@Composable
fun PermissionHandler(
onPermissionsGranted: () -> Unit
)
{
val context = LocalContext.current
val activity = context as? Activity

// State to show or hide the dialog
var showDialog by remember { mutableStateOf(false) }

// List of permissions to request based on Android version
val permissions = remember {
mutableListOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.CAMERA
).apply {
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE -> {
// Android 14 (API 34) and above
add(Manifest.permission.READ_MEDIA_IMAGES)
add(Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED)
}
Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> {
// Android 13 (API 33)
add(Manifest.permission.READ_MEDIA_IMAGES)
}
Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> {
// Android 10 (API 29)
add(Manifest.permission.ACCESS_MEDIA_LOCATION)
add(Manifest.permission.READ_EXTERNAL_STORAGE)
}
Build.VERSION.SDK_INT >= Build.VERSION_CODES.P -> {
// Android 9 (API 28)
add(Manifest.permission.READ_EXTERNAL_STORAGE)
add(Manifest.permission.WRITE_EXTERNAL_STORAGE)
}
}
}
}

// State to manage permission requests
val permissionsState = rememberMultiplePermissionsState(permissions)

// Effect to check permission status
LaunchedEffect(permissionsState.allPermissionsGranted) {
if (permissionsState.allPermissionsGranted) {
onPermissionsGranted() // Proceed if permissions are granted
} else {
showDialog = true // Show dialog if permissions are not granted
}
}

// Dialog to request permissions
if (showDialog) {
AlertDialog(
onDismissRequest = { /* Prevent dismissal by tapping outside */ },
title = { Text("Permissions Required") },
text = { Text("This app requires access to your media to function properly. Please grant the requested permissions.") },
confirmButton = {
Button(onClick = {
showDialog = false
permissionsState.launchMultiplePermissionRequest() // Launch permission request
}) {
Text("Grant Permissions")
}
},
dismissButton = {
Button(onClick = {
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
data = Uri.fromParts("package", context.packageName, null) // Open app settings
}
context.startActivity(intent)
}) {
Text("Open Settings")
}
}
)
}
}

Key Components of the Code

  • Permissions Management: The function dynamically creates a list of permissions based on the Android version. This ensures that your app only requests the necessary permissions relevant to the user’s device.
  • State Management: The function uses remember to create a mutable state variable showDialog, controlling the visibility of the permission dialog.
  • User Interface: An AlertDialog is presented to the user, offering them a choice to grant permissions or navigate to the app settings for manual permission management.
  • Dependencies: Ensure you include the required dependencies in your build.gradlefile:
dependencies {
implementation "androidx.compose.runtime:runtime:<version>" // Replace <version> with the latest version
implementation "com.google.accompanist:accompanist-permissions:<version>" // Replace <version> with the latest version
}

Conclusion

Handling permissions correctly is crucial for building responsive and user-friendly applications. ThePermissionHandler function provides a clear, concise way to manage permissions in Jetpack Compose, ensuring that your app adheres to best practices while delivering a seamless user experience. You can significantly simplify permission handling by leveraging the power of Compose and the Accompanist library.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Anil Kr Mourya
Anil Kr Mourya

Written by Anil Kr Mourya

Unlocking the Power of Developers : Your Imagination, Our Innovation. LinkedIn Profile https://www.linkedin.com/in/anil-kr-maurya-351a48283/

No responses yet

Write a response