0
0
Android Kotlinmobile~15 mins

Permission request flow in Android Kotlin - Deep Dive

Choose your learning style9 modes available
Overview - Permission request flow
What is it?
Permission request flow is the process an Android app uses to ask the user for access to sensitive features like the camera, location, or contacts. The app must request these permissions at runtime, and the user can allow or deny them. This flow ensures users control what apps can access on their device.
Why it matters
Without permission requests, apps could access private data or device features without user consent, risking privacy and security. Permission request flow protects users by making apps ask first, giving users control and trust. It also helps apps avoid crashes or errors when trying to use features they don't have access to.
Where it fits
Before learning permission request flow, you should understand basic Android app structure and how to build simple user interfaces. After this, you can learn about handling user input, managing app lifecycle, and advanced security practices.
Mental Model
Core Idea
Permission request flow is a polite conversation where the app asks the user for access, waits for their answer, and then acts accordingly.
Think of it like...
It's like borrowing a friend's car: you ask permission first, wait for their yes or no, and only then drive or not. You can't just take the keys without asking.
┌───────────────┐
│ App needs     │
│ permission   │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Ask user for  │
│ permission    │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ User grants   │
│ or denies     │
└──────┬────────┘
       │
  ┌────┴─────┐
  │          │
  ▼          ▼
Use feature  Show message
or handle    or disable
denied      feature
Build-Up - 7 Steps
1
FoundationWhat are Android permissions
🤔
Concept: Introduce what permissions are and why Android apps need them.
Android permissions are rules that protect sensitive device features and user data. Apps must declare needed permissions in a file called AndroidManifest.xml. Some permissions are 'normal' and granted automatically, but 'dangerous' permissions require asking the user at runtime.
Result
Learners understand that permissions protect privacy and that apps must declare them before use.
Knowing that permissions are a security layer helps understand why apps can't just access everything freely.
2
FoundationDifference between normal and dangerous permissions
🤔
Concept: Explain the two main permission types and their handling.
Normal permissions cover less sensitive features and are granted automatically when the app installs. Dangerous permissions protect sensitive data or features like camera or location and must be requested from the user while the app runs.
Result
Learners can identify which permissions need runtime requests and which do not.
Understanding this difference prevents confusion about why some permissions require asking the user and others don't.
3
IntermediateChecking permission status at runtime
🤔Before reading on: do you think the app can just request permission anytime, or should it check first? Commit to your answer.
Concept: Learn how to check if the app already has permission before asking the user.
Use ContextCompat.checkSelfPermission(context, permission) to see if permission is granted. If granted, proceed; if not, request permission. This avoids bothering the user unnecessarily.
Result
App can decide whether to ask for permission or continue using the feature.
Knowing to check first improves user experience by not asking repeatedly for permissions already granted.
4
IntermediateRequesting permissions from the user
🤔Before reading on: do you think requesting permission is a blocking call or asynchronous? Commit to your answer.
Concept: Learn how to ask the user for permission and handle their response.
Use ActivityCompat.requestPermissions(activity, arrayOf(permission), requestCode) to ask. The system shows a dialog. The app receives the user's answer in onRequestPermissionsResult callback, where it can check if permission was granted or denied.
Result
App can request permission and react properly to user choice.
Understanding the asynchronous nature of permission requests helps avoid bugs where the app assumes permission immediately.
5
IntermediateExplaining why permission is needed
🤔Before reading on: do you think the system always shows the reason for permission, or does the app need to explain sometimes? Commit to your answer.
Concept: Learn how to show a rationale to the user before requesting permission if needed.
If the user previously denied permission, the app should explain why it needs it before asking again. Use shouldShowRequestPermissionRationale(activity, permission) to check. Show a dialog or message explaining the benefit, then request permission again.
Result
Users understand why the app needs permission, increasing chances they grant it.
Knowing to provide rationale improves trust and reduces user frustration.
6
AdvancedHandling permanent denial and settings redirect
🤔Before reading on: if a user denies permission and selects 'Don't ask again', can the app request permission again directly? Commit to your answer.
Concept: Learn how to detect permanent denial and guide users to app settings to enable permission.
If shouldShowRequestPermissionRationale returns false after denial, it means user selected 'Don't ask again'. The app cannot request permission dialog again. Instead, show a message explaining how to enable permission manually in device settings, and provide a button to open app settings using an Intent.
Result
App gracefully handles permanent denial and helps users fix permission issues.
Understanding this prevents dead ends where the app can't function and user is stuck.
7
ExpertPermission flow with modern Android APIs
🤔Before reading on: do you think the old requestPermissions method is still the best way, or are there newer APIs? Commit to your answer.
Concept: Learn about the Activity Result API for permission requests introduced in recent Android versions.
The new Activity Result API simplifies permission requests by registering a launcher with a callback. It avoids overriding onRequestPermissionsResult and improves code clarity. Example: val requestPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted -> ... } Then launch with requestPermissionLauncher.launch(permission).
Result
App uses modern, cleaner permission request code with better lifecycle handling.
Knowing modern APIs helps write future-proof, maintainable apps and avoid legacy pitfalls.
Under the Hood
When an app requests a dangerous permission, Android shows a system dialog to the user outside the app's UI. The user's choice is recorded by the system and delivered back to the app asynchronously via a callback. The system tracks permission states per app and user, including if the user denied with 'Don't ask again'. This state controls whether the app can request permission dialogs again or must direct users to settings.
Why designed this way?
Android designed runtime permissions to protect user privacy by making access explicit and controllable. Early Android versions granted all permissions at install time, which led to privacy risks. Runtime requests give users control and transparency. The asynchronous callback model fits Android's event-driven architecture and avoids blocking the UI thread.
┌───────────────┐
│ App requests  │
│ permission   │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ System shows  │
│ dialog to     │
│ user          │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ User grants   │
│ or denies     │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ System records│
│ choice and    │
│ notifies app │
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: If a user denies a permission once, can the app never ask again? Commit yes or no.
Common Belief:Once the user denies a permission, the app cannot ask for it again.
Tap to reveal reality
Reality:The app can ask again unless the user selects 'Don't ask again'. If 'Don't ask again' is selected, the app must direct the user to settings.
Why it matters:Believing this stops developers from retrying permission requests properly, leading to poor user experience.
Quick: Do normal permissions require runtime requests? Commit yes or no.
Common Belief:All permissions must be requested at runtime.
Tap to reveal reality
Reality:Normal permissions are granted automatically at install time and do not require runtime requests.
Why it matters:Misunderstanding this causes unnecessary code and confusing user prompts.
Quick: Does requesting permission block the app until the user responds? Commit yes or no.
Common Belief:Requesting permission is a blocking call that waits for user input.
Tap to reveal reality
Reality:Permission requests are asynchronous; the app continues running and receives the result later via a callback.
Why it matters:Assuming blocking behavior can cause bugs where the app tries to use features before permission is granted.
Quick: If the user denies permission, can the app still use the feature? Commit yes or no.
Common Belief:If permission is denied, the app can still use the feature but with limited functionality.
Tap to reveal reality
Reality:If permission is denied, the app cannot use the protected feature and must handle this gracefully.
Why it matters:Ignoring denied permissions can cause app crashes or unexpected behavior.
Expert Zone
1
Some permissions are grouped; granting one permission in a group may grant others automatically, which can surprise developers.
2
The shouldShowRequestPermissionRationale method returns false both before first request and after permanent denial, so logic must carefully distinguish these cases.
3
Using the new Activity Result API avoids lifecycle issues common with onRequestPermissionsResult, especially in fragments and complex navigation.
When NOT to use
Avoid requesting permissions unnecessarily or too early, as it annoys users. For features that can degrade gracefully without permission, consider not requesting until needed. Alternatives include using less sensitive APIs or server-side processing when possible.
Production Patterns
In production, apps often request permissions just before the feature is used, show clear rationale dialogs, handle permanent denial by guiding users to settings, and use the Activity Result API for clean code. They also log permission states for analytics and gracefully disable features if permissions are missing.
Connections
User Experience Design
Permission request flow builds on UX principles of clear communication and user control.
Understanding how to explain permission needs clearly improves user trust and app adoption.
Event-driven Programming
Permission requests use asynchronous callbacks, a core pattern in event-driven systems.
Knowing event-driven concepts helps manage permission results without blocking app flow.
Privacy Law Compliance
Permission flows help apps comply with privacy laws like GDPR by obtaining explicit user consent.
Understanding permission flows aids in building legally compliant apps respecting user data rights.
Common Pitfalls
#1Requesting permission without checking if already granted.
Wrong approach:ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), 100)
Correct approach:if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), 100) }
Root cause:Not checking permission status leads to unnecessary prompts, annoying users.
#2Assuming permission is granted immediately after request call.
Wrong approach:ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.LOCATION), 101) startLocationUpdates() // called immediately
Correct approach:ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.LOCATION), 101) // startLocationUpdates() called only after permission granted in onRequestPermissionsResult
Root cause:Misunderstanding asynchronous nature causes app to use features without permission.
#3Ignoring permanent denial and repeatedly requesting permission.
Wrong approach:if (permissionDenied) { ActivityCompat.requestPermissions(this, arrayOf(permission), requestCode) }
Correct approach:if (!shouldShowRequestPermissionRationale(this, permission)) { // Show dialog to guide user to settings }
Root cause:Not handling 'Don't ask again' leads to dead-end user experience.
Key Takeaways
Android permission request flow protects user privacy by requiring apps to ask for sensitive access at runtime.
Apps must check if permission is already granted before requesting to avoid annoying users.
Permission requests are asynchronous; apps receive results via callbacks and must handle both grant and denial.
Providing clear rationale improves user trust and increases permission grant rates.
Modern Android APIs like Activity Result API simplify permission handling and improve app reliability.