← All courses

Permissions & Runtime Requests

🗓 May 31, 2026 ⏱ 1 min read

Two kinds of permissions

  • Normal (internet, vibrate) — granted automatically; just declare them in the manifest.
  • Dangerous (camera, location, contacts, microphone) — you must declare them and ask the user at runtime.

Declare in the manifest

<uses-permission android:name="android.permission.CAMERA" />

Request at runtime

val requestCamera = registerForActivityResult(
    ActivityResultContracts.RequestPermission()
) { granted ->
    if (granted) openCamera()
    else showMessage("Camera permission is needed to take photos")
}

// trigger it (e.g. on button click)
requestCamera.launch(Manifest.permission.CAMERA)

Check before using

val hasCamera = ContextCompat.checkSelfPermission(
    this, Manifest.permission.CAMERA
) == PackageManager.PERMISSION_GRANTED

Best practices

  • Ask in context — request the camera permission when the user taps “Take photo”, not on app launch.
  • Explain why — if it helps, show a short rationale before asking.
  • Handle denial gracefully — the app should still work, just without that feature.

Common mistakes

  • Declaring the permission but forgetting the runtime request (the feature silently fails).
  • Requesting everything at startup — users get scared and deny.
  • Crashing when a permission is denied instead of degrading gracefully.
Summary: Declare dangerous permissions in the manifest, request them at the moment they’re needed, and always handle the “denied” case.