Android Academy · Lesson

Handling Denials and Rationale

Explain why you need a permission.

Lesson 3 of 413 steps

Handling Denials and Rationale is a free Android Academy lesson on CoddyKit. This is lesson 3 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the Android Academy learning path, and your progress syncs across the web and the CoddyKit app. The Android Academy course includes 4 lessons in total.

Handling Denials

Users can deny a permission, and they can deny it permanently. A polished app handles all states gracefully: granted, denied once, and denied with "don't ask again".

Three Possible States

After a request you may be in one of three states:

  • Granted: proceed with the feature
  • Denied (can ask again): explain and re-request
  • Permanently denied: the dialog no longer appears; guide the user to Settings

What Is Rationale

A rationale is a short explanation of why your app needs a permission. Android tells you when to show one via shouldShowRequestPermissionRationale.

shouldShowRequestPermissionRationale

This method returns true when the user has denied the permission at least once but has not selected "don't ask again". That is your cue to explain before requesting again.

val activity = LocalContext.current as Activity
val showRationale = ActivityCompat
    .shouldShowRequestPermissionRationale(
        activity,
        Manifest.permission.CAMERA
    )

Reading the Signal

Interpreting the value together with the grant check:

  • Granted: nothing to do
  • Not granted and shouldShowRationale == true: show an explanation, then re-request
  • Not granted and shouldShowRationale == false: either first ask, or permanently denied

Showing a Rationale Dialog

When rationale is needed, present a friendly dialog before launching the system request again, so the user understands the value.

if (showRationale) {
    AlertDialog(
        onDismissRequest = { },
        title = { Text("Camera needed") },
        text = { Text("We use the camera to scan codes.") },
        confirmButton = {
            TextButton(onClick = {
                launcher.launch(Manifest.permission.CAMERA)
            }) { Text("Continue") }
        }
    )
}

Detecting Permanent Denial

If the permission is still not granted and shouldShowRationale is false after the user has already been asked, treat it as permanently denied. The system dialog will not appear anymore.

Tracking Whether You Asked

Because shouldShowRationale is also false on the very first request, track a flag (e.g. in DataStore) recording that you asked at least once, so you can distinguish first-ask from permanent denial.

Sending Users to Settings

For permanent denial, you cannot re-prompt. Offer a button that opens your app's settings page so the user can grant the permission manually.

fun openAppSettings(context: Context) {
    val intent = Intent(
        Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
        Uri.fromParts("package", context.packageName, null)
    )
    context.startActivity(intent)
}

Designing the Denied UI

Never leave a blank or broken screen when denied. Show a clear message, explain the impact, and offer the right action: re-request, open Settings, or continue with reduced functionality.

Respect the User's Choice

Do not nag. If the user denied, do not bombard them on every screen. Re-ask only when they take an action that needs the feature, and gracefully degrade otherwise.

Quick Check

Test your understanding of denials and rationale.

Recap

You learned to handle denials:

  • Three states: granted, denied, permanently denied
  • shouldShowRequestPermissionRationale signals when to explain
  • Track whether you have asked to detect permanent denial
  • For permanent denial, send the user to app Settings
  • Design a clear denied-state UI and avoid nagging

Next: privacy best practices.

Free to start

Learn Kotlin with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
36
Lessons
152

Frequently Asked Questions

Is the “Handling Denials and Rationale” lesson free?

Yes — any 3 lessons of the Android Academy learning path, including “Handling Denials and Rationale”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The Android Academy course includes 4 lessons in total.

What will I learn in “Handling Denials and Rationale”?

Explain why you need a permission. You practise Android Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Android Academy?

No prior experience is required. Android Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 3 of 4.

How long does the “Handling Denials and Rationale” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Android Academy lesson?

Yes. Every Android Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. The Android Permission Model
  2. Requesting Permissions in Compose
  3. Handling Denials and Rationale
  4. Best Practices for Privacy
← Back to Android Academy