Android Runtime Permissions & Scoped Storage Compliance

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.

Modern Android Runtime Permissions Workflow

Figure 21.1: Modern Android Runtime Permissions Flowchart — From Initial State Check to Educational Rationale and ActivityResultContracts.

The 4-Step Runtime Permission Workflow

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() }
}

Frequently Asked Questions (FAQ) - Student & Interview Review

Q1. What happens if a user checks 'Don't ask again' on a permission prompt?

The system dialog will never show again. Any future request calls will automatically return `isGranted = false`. If the user must have this permission, your app must direct them to `Settings > Apps > YourApp > Permissions` via an Intent with `ACTION_APPLICATION_DETAILS_SETTINGS`.

Q2. What is the new POST_NOTIFICATIONS permission in Android 13+?

Starting in Android 13 (API 33), apps can no longer post notifications to the system tray without asking for the runtime permission `android.permission.POST_NOTIFICATIONS`. If denied, notifications are silently dropped.

Q3. What are granular media permissions introduced in Android 13?

The broad `READ_EXTERNAL_STORAGE` permission was split into granular permissions: `READ_MEDIA_IMAGES`, `READ_MEDIA_VIDEO`, and `READ_MEDIA_AUDIO`. Apps should only ask for the specific media type they actually need.

Explore Related Android Development Classes & Next Steps

Broaden your foundational and advanced Android application development skills across our curriculum:

AndroidManifest.xml Configuration

Declare uses-permission tags and target SDK constraints.

ContentProviders & Scoped Storage

Access media files without broad external storage permissions.

App Security & Android KeyStore

Secure encryption keys and biometric authorization flags.

Passkeys & Biometric Authentication

BiometricPrompt authentication without legacy password prompts.

Share Share on Facebook Share on Twitter Share on LinkedIn Pin on Pinterest Share on Reddit

You may also like this!