Apps need permission to access sensitive features like camera or location. This flow helps ask users for permission politely.
Permission request flow in Android Kotlin
if (ContextCompat.checkSelfPermission(this, Manifest.permission.PERMISSION_NAME) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.PERMISSION_NAME), REQUEST_CODE) } else { // Permission already granted }
Replace PERMISSION_NAME with the actual permission like CAMERA or ACCESS_FINE_LOCATION.
REQUEST_CODE is a number you choose to identify this permission request.
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), 100) } else { // Camera permission already granted }
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == 100) {
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
// Permission granted, proceed
} else {
// Permission denied, show message
}
}
}This app checks if the camera permission is granted when it starts. If not, it asks the user. It shows a small message depending on the user's choice.
import android.Manifest import android.content.pm.PackageManager import android.os.Bundle import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat class MainActivity : AppCompatActivity() { private val CAMERA_REQUEST_CODE = 100 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) checkCameraPermission() } private fun checkCameraPermission() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), CAMERA_REQUEST_CODE) } else { Toast.makeText(this, "Camera permission already granted", Toast.LENGTH_SHORT).show() } } override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == CAMERA_REQUEST_CODE) { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { Toast.makeText(this, "Camera permission granted", Toast.LENGTH_SHORT).show() } else { Toast.makeText(this, "Camera permission denied", Toast.LENGTH_SHORT).show() } } } }
Always explain why you need the permission before asking.
Users can deny permission permanently; handle that case gracefully.
Test on devices with different Android versions because permission behavior can vary.
Check if permission is already granted before asking.
Request permission using ActivityCompat.requestPermissions.
Handle user response in onRequestPermissionsResult.
Practice
Solution
Step 1: Understand permission checking
Before asking for permission, the app must check if it already has it to avoid unnecessary requests.Step 2: Use ContextCompat.checkSelfPermission
This method returns if the permission is granted or denied, guiding the next action.Final Answer:
Check if the permission is already granted -> Option DQuick Check:
Check permission first = A [OK]
- Requesting permission without checking first
- Assuming permission is granted by default
- Ignoring permission status before action
Solution
Step 1: Identify correct method signature
ActivityCompat.requestPermissions requires context, array of permissions, and request code.Step 2: Check syntax correctness
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), 100) matches the correct syntax with 'this' as context and arrayOf for permissions.Final Answer:
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), 100) -> Option AQuick Check:
Correct requestPermissions syntax = D [OK]
- Passing single permission string instead of array
- Using wrong method name or class
- Missing context parameter
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == 101 && grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
println("Permission granted")
} else {
println("Permission denied")
}
}
What will be printed if the user denies the permission?Solution
Step 1: Analyze grantResults array
If the user denies permission, grantResults[0] will not equal PERMISSION_GRANTED.Step 2: Follow conditional logic
The else branch executes, printing "Permission denied".Final Answer:
Permission denied -> Option AQuick Check:
User denies permission = "Permission denied" [OK]
- Assuming grantResults[0] is always granted
- Not checking if grantResults is empty
- Ignoring requestCode check
ActivityCompat.requestPermissions(this, Manifest.permission.ACCESS_FINE_LOCATION, 200)
Solution
Step 1: Check method parameters
requestPermissions expects an array of permissions, not a single string.Step 2: Identify correct usage
Permission string must be wrapped in arrayOf() to form an array.Final Answer:
Missing arrayOf() around permission string -> Option BQuick Check:
Permissions must be in arrayOf() [OK]
- Passing single permission string instead of array
- Confusing ContextCompat with ActivityCompat
- Using invalid request codes
Solution
Step 1: Request multiple permissions correctly
Use arrayOf with both permissions and a unique request code.Step 2: Check all permissions granted in onRequestPermissionsResult
Use grantResults.all { it == PackageManager.PERMISSION_GRANTED } to verify all permissions.Final Answer:
Request both permissions and check all granted with grantResults.all -> Option CQuick Check:
Multiple permissions need all granted check [OK]
- Checking only first permission result
- Not using arrayOf for multiple permissions
- Ignoring requestCode in result handler
Ready to prove it?
Pass the test and this pattern moves unknown
