Lesson 24: Handling Permissions in Android
Handling Permissions in Android
Some features — camera, precise location, notifications — require the user's explicit permission, requested at runtime rather than just declared upfront.
Step 1: declare it in the manifest
<!-- AndroidManifest.xml -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />This is necessary but not sufficient — for "dangerous" permissions like this, you also have to ask the user directly while the app is running.
Step 2: request it at runtime, in Compose
@Composable
fun NotificationPermissionRequest() {
val permissionState = rememberPermissionState(
android.Manifest.permission.POST_NOTIFICATIONS
)
LaunchedEffect(Unit) {
if (!permissionState.status.isGranted) {
permissionState.launchPermissionRequest()
}
}
}(This uses the Accompanist Permissions library — add implementation("com.google.accompanist:accompanist-permissions:0.34.0") to use rememberPermissionState.)
LaunchedEffect — running code once, safely
LaunchedEffect(Unit) is new here: it runs the code inside it exactly once when the composable first appears (the Unit means "never re-run this unless the whole composable leaves and re-enters"). This is the correct way to run a one-time side effect — like a permission request — from inside a composable, rather than putting it directly in the function body where it would re-run on every recomposition.
Handling "denied" gracefully
if (permissionState.status.shouldShowRationale) {
Text("We need this permission to remind you about tasks.")
}If a user denies a permission once, Android gives your app a chance to explain why you need it before they're asked again — always show a clear reason rather than just repeatedly requesting the same permission with no context, which reads as spammy and often gets your app permanently blocked from asking again.
Next: Lesson 25 — loading real images from the internet with Coil.