Android development / Editorial solution guide

Diagnose permission denial and missing notifications

Separate device API, target behavior, runtime grants, and notification channels before changing a permission flow.

About 3 min readContent reviewed

Read-only knowledge base · No public comments

Recognize the symptoms

A camera feature stops after returning from settings, a permission dialog no longer appears, or reminders remain invisible after the user grants access. Notification behavior may differ across fresh installs and upgraded devices. Capture the device API, application targetSdk, install history, exact action that requests access, runtime grant, and channel state. A screenshot of one dialog is insufficient to explain the complete integration.

Understand the likely causes

  • A manifest declaration does not grant a dangerous permission at runtime. Grants can be revoked, repeated denial can change prompt behavior, and a stored Boolean can become stale. Notifications have additional gates: POST_NOTIFICATIONS on API 33+, application settings, channels on API 26+, and correct posting configuration. INTERNET is a normal permission and should not be mixed into a dangerous-permission request flow.

Check the API path and declaration

Determine whether the feature truly needs the permission. A system photo picker can provide selected images without broad media access, and launching an external capture contract differs from opening camera hardware directly. Inspect the merged manifest for the specific required declaration. Then check current permission immediately before the protected operation. If access is absent, render a supported unavailable state rather than allowing SecurityException to become the first indication. Do not restore a previously saved grant flag as authority after process recreation.

Request from an intentional user action

Register an Activity Result permission contract with a stable lifecycle owner and launch it when the user invokes the feature. Show a rationale when appropriate, allow cancellation, and keep unrelated functionality available. Rationale APIs do not perfectly encode every denial history, so avoid assuming a false result always means first request or permanent denial. Where the system cannot show another prompt, offer an explanatory settings route when the user wants the feature. Repeating a request on every render is not a recovery strategy.

Inspect notification gates separately

On Android 13, API 33, and later, non-exempt notifications require POST_NOTIFICATIONS. Apps targeting API 33+ control prompt timing more directly than older targets. On API 26+, inspect the exact channel used by the reminder: a granted runtime permission does not override a blocked channel. The check below reports the runtime gate only. Also verify channel creation, notification construction, and app-level settings. Starting a foreground service does not itself require this notification grant, but the foreground-service notification contract still applies.

kotlin A runtime gate, not a delivery guarantee
fun notificationRuntimeGranted(context: Context): Boolean {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) return true
    return ContextCompat.checkSelfPermission(
        context, Manifest.permission.POST_NOTIFICATIONS
    ) == PackageManager.PERMISSION_GRANTED
}

Use an SDK defining API 33 symbols, declare POST_NOTIFICATIONS, and import ContextCompat and platform classes. true on an older device means this runtime gate is inapplicable; app settings and channel rules still matter. This helper neither prompts nor posts a notification.

Verify the fix

Verify fresh denial, approval, revocation in settings, return to the app, and a blocked reminder channel independently. After each transition, invoke the actual feature and confirm the UI matches current access. For notifications, test a relevant API and target matrix, then verify a posted notification on the intended channel instead of concluding success from the permission callback alone. Preserve the user’s chosen denial.

Keep it from recurring

  • Keep version checks near the platform integration and document which gate each helper evaluates. Request least access in context, refresh capability state after settings changes, and test denied states alongside successful paths. Link support messages to the specific unavailable feature rather than presenting every notification failure as a reason to request all permissions again.

Official references