Sensitive features (camera, location, contacts) need the user's permission at runtime, not just in the manifest.
Declare in the manifest
<uses-permission android:name="android.permission.CAMERA"/>
Ask at runtime
val launcher = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { granted ->
if (granted) openCamera() else showRationale()
}
// trigger it
launcher.launch(Manifest.permission.CAMERA)
Good UX
- Explain why you need a permission before asking.
- Handle the "denied" case gracefully — never crash.
- If permanently denied, guide the user to Settings.
Common mistake: Requesting many permissions on first launch scares users and hurts Play Store approval. Ask only when the feature is used.
Summary
Declare permissions in the manifest and request dangerous ones at runtime with a clear explanation and graceful fallbacks.