Runtime Permission — механизм запроса разрешений во время выполнения приложения, введённый в Android 6.0 (API 23). В отличие от установки permissions при инсталляции, runtime permissions позволяют пользователю предоставлять или отзывать доступ к конфиденциальным данным (камера, геолокация, контакты) в любой момент. По данным Android Developers (2026), более 85% приложений в Google Play используют хотя бы одно runtime permission.
Главное
Runtime Permission (разрешение времени выполнения) — это модель безопасности Android, при которой приложение запрашивает доступ к конфиденциальным данным в момент, когда эта функциональность действительно нужна пользователю. До Android 6.0 все разрешения предоставлялись при установке приложения, и пользователь не мог отозвать их без полного удаления приложения.
До Android 6.0 пользователь видел список всех разрешений при установке и мог либо согласиться на все, либо отказаться от установки. Исследование 2015 года показало, что 87% пользователей не читают список разрешений при установке. Android 6.0 ввёл runtime permissions, разделив разрешения на normal (автоматические) и dangerous (с запросом). Android 11 добавил one-time permissions — автоматический отзыв после закрытия приложения. Android 13 ввёл Photo Picker и push-уведомления как отдельные runtime permissions.
iOS использует аналогичную модель с версии iOS 10, где доступ к камере, микрофону и геолокации запрашивается при первом обращении. Однако iOS не имеет понятия «normal permissions» — каждое разрешение запрашивается явно, а отказ сохраняется до повторного запроса разработчиком через системные настройки.
Runtime Permission работает через системный диалог, вызываемый методом requestPermissions() (AndroidX — ActivityResultLauncher). Система показывает стандартный диалог с объяснением, и пользователь выбирает «Разрешить» или «Запретить». После ответа вызывается колбэк результата, где приложение обрабатывает решение пользователя.
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)
}
}
}
Метод shouldShowRequestPermissionRationale возвращает true, если пользователь уже один раз отклонил запрос. В этом случае рекомендуется показать диалог с объяснением, зачем приложению нужно разрешение, и только затем повторно запрашивать. Это повышает вероятность согласия пользователя на 30–40% (данные Google I/O 2024).
Android классифицирует все разрешения на несколько уровней защиты: normal, dangerous, signature и special. Normal permissions предоставляются автоматически при установке. Dangerous permissions требуют runtime-запроса. Signature permissions доступны только приложениям, подписанным тем же сертификатом.
| Группа | Разрешения | API Level |
|---|---|---|
| CAMERA | CAMERA | API 23+ |
| LOCATION | ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION, ACCESS_BACKGROUND_LOCATION | API 23+ (background — API 29+) |
| STORAGE | READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE, READ_MEDIA_IMAGES (API 33+) | API 23+ (изменения в API 33) |
| PHONE | READ_PHONE_STATE, CALL_PHONE, READ_CALL_LOG | API 23+ |
| MICROPHONE | RECORD_AUDIO | API 23+ |
| CONTACTS | READ_CONTACTS, WRITE_CONTACTS, GET_ACCOUNTS | API 23+ |
| NOTIFICATIONS | POST_NOTIFICATIONS | API 33+ |
Special permissions (SYSTEM_ALERT_WINDOW, WRITE_SETTINGS, MANAGE_EXTERNAL_STORAGE) требуют дополнительного перехода в системные настройки через Settings.ACTION_MANAGE_OVERLAY_PERMISSION. Эти разрешения не могут быть запрошены стандартным системным диалогом и требуют явного перехода пользователя в экран настроек.
Android 12 представил значительные изменения в модели runtime permissions. One-time permissions позволяют предоставить доступ к камере, микрофону или геолокации только на один сеанс. Как только пользователь закрывает приложение, разрешение автоматически отзывается. Privacy indicators — зелёные индикаторы в строке состояния, показывающие, когда приложение использует камеру или микрофон.
// Android 12+ — обработка одноразового разрешения на геолокацию
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
)
)
}
// Проверка, было ли разрешение отозвано системой (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 добавил разрешение POST_NOTIFICATIONS в группу dangerous, требуя явного запроса на отправку push-уведомлений. Android 14 ввёл ограничения на фоновую геолокацию: приложение должно получать явное одобрение пользователя каждый раз при запросе background location. Photo Picker (API 33+) заменил необходимость в READ_EXTERNAL_STORAGE для выбора изображений.
Отказ пользователя в предоставлении разрешения — штатная ситуация, которую необходимо корректно обрабатывать. Существует два типа отказа: однократный (пользователь нажал «Запретить») и постоянный (пользователь выбрал «Больше не спрашивать»). Во втором случае системный диалог больше не показывается, и приложение должно перенаправить пользователя в системные настройки.
После первого отказа приложение должно показать rationale dialog — собственное объяснение, почему разрешение необходимо. Если пользователь отказывается повторно, следует перенаправить его в экран настроек приложения через Settings.ACTION_APPLICATION_DETAILS_SETTINGS. Material 3 рекомендует использовать PermissionRequestBottomSheet для более естественного UX.
Важно не блокировать полностью функциональность приложения при отказе. Например, если пользователь отклонил геолокацию, приложение должно предложить ввести адрес вручную. Для камеры — дать возможность загрузить изображение из галереи. Google рекомендует всегда предоставлять fallback-механизм для всех runtime permissions.
Runtime permissions — не только технический механизм, но и элемент доверия пользователя к приложению. Запрос разрешения в неподходящий момент (например, при первом запуске) значительно снижает вероятность согласия. Google Play Store анализирует частоту и контекст запросов разрешений: приложения с агрессивными запросами получают более низкие позиции в поиске.
Контекст — запрашивайте разрешение непосредственно перед выполнением действия, которое его требует. Минимум — запрашивайте только те разрешения, которые действительно необходимы для работы функции. Прозрачность — объясните пользователю, зачем нужно разрешение, перед системным диалогом. Отзыв — подписывайтесь на ACTION_PERMISSION_REVOCATION для корректной обработки отзыва разрешения в рантайме.
Для тестирования runtime permissions используйте adb команды: adb shell pm revoke <package> android.permission.CAMERA позволяет симулировать отзыв разрешения без переустановки приложения. Espresso и UiAutomator поддерживают тестирование permission-диалогов через GrantPermissionRule. Интеграция этих инструментов в CI/CD пайплайн обязательна для приложений с runtime permissions.
Google Play Console предоставляет раздел Permission auditing (аудит разрешений), где разработчик видит, как часто запрашиваются разрешения, какой процент пользователей предоставляет доступ и какие разрешения были отозваны. Анализ этих данных помогает выявить неэффективные запросы и оптимизировать UX. Например, если менее 40% пользователей предоставляют геолокацию, стоит пересмотреть тайминг запроса и добавить более убедительный rationale.
Использование Android Vitals для мониторинга permission-related ANR (Application Not Responding) также критично. Если запрос разрешения выполняется на главном потоке или системный диалог блокирует UI, это может вызвать ANR на медленных устройствах. Выносите проверку и запрос разрешений в отдельный поток или используйте корутины Kotlin для асинхронной обработки, чтобы избежать блокировки пользовательского интерфейса.
Часто задаваемые вопросы
shouldShowRequestPermissionRationale возвращает false при постоянном отказе (когда пользователь выбрал «Больше не спрашивать»). Метод возвращает true при однократном отказе, позволяя показать rationale диалог. Если метод вернул false, единственный выход — перенаправить пользователя в системные настройки приложения.
Да, ActivityResultContracts.RequestMultiplePermissions позволяет запросить массив разрешений за один вызов. Система покажет последовательно диалоги для каждого разрешения. Рекомендуется группировать логически связанные разрешения (например, CAMERA и RECORD_AUDIO для видеосъёмки), но не запрашивать более 2–3 за один раз.
Android TV использует ту же модель runtime permissions с отображением диалогов на телевизионном экране. Wear OS версии 3+ поддерживает runtime permissions, но диалоги отображаются на часах. Для Android Auto все разрешения запрашиваются на телефоне, а автомобильная система получает уже одобренные permissions через bridge-соединение.
По предварительной информации Android 16 вводит «permission expiration» для одноразовых разрешений с автоматическим отзывом через 24 часа. Также ожидается ужесточение требований к background location и расширение списка dangerous permissions для новых категорий (сенсоры окружения, Wi-Fi scanning). Точные детали появятся в Q3 2027.
iOS не поддерживает «normal permissions» — каждое разрешение запрашивается явно через системный диалог. Пользователь может отозвать разрешение в любой момент через настройки. Основное отличие — iOS предварительно не проверяет статус разрешения через аналог checkSelfPermission: система автоматически показывает диалог при первом обращении к защищённому API.
Итоги
POST_NOTIFICATIONS как runtime permission, Android 14 ужесточил требования к фоновой геолокации.READ_EXTERNAL_STORAGE для выбора изображений.Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также