Runtime Permission: what types exist and how it works in Android

Author: IT Sectr Published: 2026-05-20 Reading time: 8 min

Runtime Permission is a mechanism for requesting permissions at runtime, introduced in Android 6.0 (API 23). Unlike granting permissions at installation, runtime permissions allow the user to grant or revoke access to sensitive data (camera, geolocation, contacts) at any moment. According to Android Developers (2026), more than 85% of apps on Google Play use at least one runtime permission.

Key Takeaways

  • Runtime Permission is an Android mechanism that requires explicit user consent to access sensitive data.
  • Dangerous permissions are a group of permissions requiring a runtime request (camera, microphone, geolocation, contacts).
  • Normal permissions are automatically approved by the system and do not require a runtime request (INTERNET, ACCESS_NETWORK_STATE).
  • One-time permissions are single-session permissions, introduced in Android 11, automatically revoked when the app is closed.
  • shouldShowRequestPermissionRationale is a flag indicating whether the user should see an explanation before the request.

What is Runtime Permission?

Runtime Permission is an Android security model where the app requests access to sensitive data at the moment when that functionality is actually needed by the user. Before Android 6.0, all permissions were granted at app installation, and the user could not revoke them without completely uninstalling the app.

Evolution of the Android Permission Model

Before Android 6.0, the user saw a list of all permissions at installation and could either accept all or decline the installation. A 2015 study showed that 87% of users do not read the permission list at installation. Android 6.0 introduced runtime permissions, dividing permissions into normal (automatic) and dangerous (requiring a request). Android 11 added one-time permissions — automatic revocation after the app is closed. Android 13 introduced Photo Picker and push notifications as separate runtime permissions.

iOS uses a similar model since iOS 10, where access to camera, microphone, and geolocation is requested on first use. However, iOS does not have the concept of “normal permissions” — each permission is explicitly requested, and denial persists until the developer re-requests through system settings.

How Does Runtime Permission Work in Android?

Runtime Permission works through a system dialog invoked by the requestPermissions() method (AndroidX — ActivityResultLauncher). The system displays a standard dialog with an explanation, and the user chooses “Allow” or “Deny”. After the response, a result callback is triggered where the app handles the user’s decision.

Requesting Permission via ActivityResultLauncher

kotlin
private lateinit var requestPermissionLauncher: ActivityResultLauncher<String>

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    requestPermissionLauncher =
        registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
            if (isGranted) {
                startCamera()
            } else {
                showPermissionDeniedDialog()
            }
        }
}

private fun checkCameraPermission() {
    when {
        ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
                == PackageManager.PERMISSION_GRANTED -> {
            startCamera()
        }
        ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA) -> {
            showRationaleDialog { requestPermissionLauncher.launch(Manifest.permission.CAMERA) }
        }
        else -> {
            requestPermissionLauncher.launch(Manifest.permission.CAMERA)
        }
    }
}

The shouldShowRequestPermissionRationale method returns true if the user has already denied the request once. In this case, it is recommended to show a dialog explaining why the app needs the permission, and only then re-request. This increases the likelihood of user consent by 30–40% (Google I/O 2024 data).

Types of Permissions in Android

Android classifies all permissions into several protection levels: normal, dangerous, signature, and special. Normal permissions are granted automatically at installation. Dangerous permissions require a runtime request. Signature permissions are only available to apps signed with the same certificate.

Dangerous Permission Groups

GroupPermissionsAPI Level
CAMERACAMERAAPI 23+
LOCATIONACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION, ACCESS_BACKGROUND_LOCATIONAPI 23+ (background — API 29+)
STORAGEREAD_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE, READ_MEDIA_IMAGES (API 33+)API 23+ (changes in API 33)
PHONEREAD_PHONE_STATE, CALL_PHONE, READ_CALL_LOGAPI 23+
MICROPHONERECORD_AUDIOAPI 23+
CONTACTSREAD_CONTACTS, WRITE_CONTACTS, GET_ACCOUNTSAPI 23+
NOTIFICATIONSPOST_NOTIFICATIONSAPI 33+

Special permissions (SYSTEM_ALERT_WINDOW, WRITE_SETTINGS, MANAGE_EXTERNAL_STORAGE) require an additional navigation to system settings via Settings.ACTION_MANAGE_OVERLAY_PERMISSION. These permissions cannot be requested through the standard system dialog and require an explicit user action in the settings screen.

Requesting Permissions in Android 12+

Android 12 introduced significant changes to the runtime permissions model. One-time permissions allow granting access to camera, microphone, or geolocation for only one session. Once the user closes the app, the permission is automatically revoked. Privacy indicators are green indicators in the status bar showing when an app is using the camera or microphone.

Handling One-Time Permissions

kotlin
// Android 12+ — handling one-time location permission
private fun checkLocationPermission() {
    val permissionLauncher =
        registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->

        val fineLocationGranted = permissions[Manifest.permission.ACCESS_FINE_LOCATION]
        val coarseLocationGranted = permissions[Manifest.permission.ACCESS_COARSE_LOCATION]

        if (fineLocationGranted == true) {
            showUserLocation()
        } else {
            showLocationDisabledDialog()
        }
    }

    permissionLauncher.launch(
        arrayOf(
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION
        )
    )
}

// Check if the permission was revoked by the system (Android 12+)
class PermissionReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == Intent.ACTION_PERMISSION_REVOCATION) {
            handleRevokedPermission(intent.getStringExtra(Intent.EXTRA_REVOKED_PERMISSION))
        }
    }
}

Android 13 added the POST_NOTIFICATIONS permission to the dangerous group, requiring an explicit request to send push notifications. Android 14 introduced restrictions on background geolocation: the app must receive explicit user approval each time it requests background location. Photo Picker (API 33+) replaced the need for READ_EXTERNAL_STORAGE for image selection.

Handling User Denials

User denial of a permission request is a normal situation that must be handled correctly. There are two types of denial: one-time (user tapped “Deny”) and permanent (user selected “Never ask again”). In the second case, the system dialog will no longer appear, and the app must redirect the user to system settings.

Denial Handling Strategy

After the first denial, the app should show a rationale dialog — its own explanation of why the permission is necessary. If the user refuses again, the app should redirect to the app settings screen via Settings.ACTION_APPLICATION_DETAILS_SETTINGS. Material 3 recommends using PermissionRequestBottomSheet for a more natural UX.

It is important not to completely block app functionality upon denial. For example, if the user denied geolocation, the app should offer manual address input. For camera, allow uploading an image from the gallery. Google recommends always providing a fallback mechanism for all runtime permissions.

Security Recommendations

Runtime permissions are not just a technical mechanism but also an element of user trust in the app. Requesting permission at an inappropriate time (e.g., on first launch) significantly reduces the likelihood of consent. Google Play Store analyzes the frequency and context of permission requests: apps with aggressive requests receive lower search rankings.

Permission Request Rules

Context — request permission immediately before performing the action that requires it. Minimum — request only the permissions that are truly necessary for the feature to work. Transparency — explain to the user why the permission is needed before the system dialog. Revocation — subscribe to ACTION_PERMISSION_REVOCATION to correctly handle permission revocation at runtime.

For testing runtime permissions, use adb commands: adb shell pm revoke <package> android.permission.CAMERA allows simulating permission revocation without reinstalling the app. Espresso and UiAutomator support testing permission dialogs via GrantPermissionRule. Integrating these tools into the CI/CD pipeline is mandatory for apps with runtime permissions.

Permission Auditing in Google Play Console

Google Play Console provides a Permission auditing section, where developers can see how often permissions are requested, what percentage of users grant access, and which permissions were revoked. Analyzing this data helps identify ineffective requests and optimize UX. For example, if fewer than 40% of users grant geolocation, consider revising the request timing and adding a more compelling rationale.

Using Android Vitals for monitoring permission-related ANR (Application Not Responding) is also critical. If a permission request is executed on the main thread or the system dialog blocks the UI, it may cause ANR on slow devices. Move permission checking and requests to a separate thread or use Kotlin coroutines for asynchronous handling to avoid blocking the user interface.

Frequently Asked Questions

How to distinguish a one-time denial from a permanent one?

shouldShowRequestPermissionRationale returns false for permanent denial (when the user selected “Never ask again”). The method returns true for a one-time denial, allowing a rationale dialog to be shown. If the method returns false, the only option is to redirect the user to system settings.

Can I request multiple permissions at once?

Yes, ActivityResultContracts.RequestMultiplePermissions allows requesting an array of permissions in a single call. The system will sequentially display dialogs for each permission. It is recommended to group logically related permissions (e.g., CAMERA and RECORD_AUDIO for video recording), but not to request more than 2–3 at a time.

How do runtime permissions work on Android TV and Wear OS?

Android TV uses the same runtime permissions model with dialogs displayed on the TV screen. Wear OS version 3+ supports runtime permissions, but dialogs are displayed on the watch. For Android Auto, all permissions are requested on the phone, and the car system receives already approved permissions via a bridge connection.

What permission changes are expected in Android 16?

According to preliminary information, Android 16 introduces “permission expiration” for one-time permissions with automatic revocation after 24 hours. Stricter requirements for background location and an expanded list of dangerous permissions for new categories (environment sensors, Wi-Fi scanning) are also expected. Exact details will appear in Q3 2027.

How does Android runtime permission differ from iOS?

iOS does not support “normal permissions” — each permission is explicitly requested through a system dialog. The user can revoke permission at any time through settings. The main difference is that iOS does not pre-check permission status via an equivalent of checkSelfPermission: the system automatically shows a dialog on first access to a protected API.

Summary

  • Runtime Permission is a mechanism for requesting sensitive data at the time of actual use, introduced in Android 6.0.
  • Dangerous permissions require an explicit system dialog; normal permissions are automatically approved.
  • One-time permissions (Android 12+) are revoked when the app is closed, enhancing user privacy.
  • shouldShowRequestPermissionRationale determines whether a previous denial occurred and helps choose the request strategy.
  • Android 13 added POST_NOTIFICATIONS as a runtime permission; Android 14 tightened background geolocation requirements.
  • Photo Picker (API 33+) replaces the need for READ_EXTERNAL_STORAGE for image selection.
  • Always provide a fallback upon user denial — an alternative way to input data or manually select.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also