Prior to Android 6.0 Marshmallow, users were forced to grant all permissions at install time on Google Play. If an app requested 20 permissions, the user had to accept all or decline installation. Today, Android enforces Runtime Permissions — applications must request sensitive permissions at the precise moment the feature is needed.
Figure 21.1: Modern Android Runtime Permissions Flowchart — From Initial State Check to Educational Rationale and ActivityResultContracts.
import android.Manifest
import android.content.pm.PackageManager
import androidx.activity.ComponentActivity
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
class CameraScreenActivity : ComponentActivity() {
// 1. Register permission contract
private val requestCameraPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted: Boolean ->
if (isGranted) {
openCameraHardware()
} else {
showPermissionDeniedSnackbar()
}
}
// 2. Trigger check before using sensitive hardware
fun onUserTapsCameraButton() {
when {
ContextCompat.checkSelfPermission(
this,
Manifest.permission.CAMERA
) == PackageManager.PERMISSION_GRANTED -> {
// Permission already granted!
openCameraHardware()
}
shouldShowRequestPermissionRationale(Manifest.permission.CAMERA) -> {
// User denied previously: Show friendly educational dialog explaining WHY
showEducationalDialog {
requestCameraPermissionLauncher.launch(Manifest.permission.CAMERA)
}
}
else -> {
// First-time request: Launch system prompt directly
requestCameraPermissionLauncher.launch(Manifest.permission.CAMERA)
}
}
}
private fun openCameraHardware() { /* Start camera */ }
private fun showPermissionDeniedSnackbar() { /* Feedback */ }
private fun showEducationalDialog(onAccept: () -> Unit) { onAccept() }
}
Broaden your foundational and advanced Android application development skills across our curriculum:
Declare uses-permission tags and target SDK constraints.
Access media files without broad external storage permissions.
Secure encryption keys and biometric authorization flags.
BiometricPrompt authentication without legacy password prompts.