Runtime Permission — механізм запиту дозволів під час виконання застосунку, представлений в Android 6.0 (API 23). На відміну від надання дозволів під час інсталяції, 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, розділивши дозволи на звичайні (автоматичні) та небезпечні (із запитом). Android 11 додав одноразові дозволи — автоматичне відкликання після закриття застосунку. Android 13 ввів Photo Picker і push-сповіщення як окремі runtime permissions.
iOS використовує подібну модель з версії iOS 10, де доступ до камери, мікрофона та геолокації запитується при першому зверненні. Однак iOS не має поняття «звичайних дозволів» — кожен дозвіл запитується явно, а відмова зберігається до повторного запиту розробником через системні налаштування.
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 класифікує всі дозволи на кілька рівнів захисту: звичайні, небезпечні, підпису та спеціальні. Звичайні дозволи надаються автоматично під час інсталяції. Небезпечні дозволи потребують runtime-запиту. Дозволи підпису доступні лише застосункам, підписаним тим самим сертифікатом.
| Група | Дозволи | API Level |
|---|---|---|
| CAMERA | CAMERA | API 23+ |
| LOCATION | ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION, ACCESS_BACKGROUND_LOCATION | API 23+ (фоновий — 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+ |
Спеціальні дозволи (SYSTEM_ALERT_WINDOW, WRITE_SETTINGS, MANAGE_EXTERNAL_STORAGE) потребують додаткового переходу в системні налаштування через Settings.ACTION_MANAGE_OVERLAY_PERMISSION. Ці дозволи не можуть бути запитані стандартним системним діалогом і потребують явного переходу користувача в екран налаштувань.
Android 12 представив значні зміни в моделі runtime permissions. Одноразові дозволи дозволяють надати доступ до камери, мікрофона або геолокації лише на один сеанс. Як тільки користувач закриває застосунок, дозвіл автоматично відкликається. Індикатори приватності — зелені індикатори в рядку стану, які показують, коли застосунок використовує камеру або мікрофон.
// 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 до групи небезпечних, вимагаючи явного запиту на надсилання push-сповіщень. Android 14 ввів обмеження на фонову геолокацію: застосунок повинен отримувати явне схвалення користувача щоразу при запиті фонового розташування. 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 надає розділ аудиту дозволів, де розробник бачить, як часто запитуються дозволи, який відсоток користувачів надає доступ і які дозволи були відкликані. Аналіз цих даних допомагає виявити неефективні запити та оптимізувати UX. Наприклад, якщо менше 40% користувачів надають геолокацію, варто переглянути таймінг запиту та додати більш переконливе обґрунтування.
Використання Android Vitals для моніторингу permission-related ANR (Application Not Responding) також критичне. Якщо запит дозволу виконується на головному потоці або системний діалог блокує інтерфейс, це може викликати 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 всі дозволи запитуються на телефоні, а автомобільна система отримує вже схвалені дозволи через bridge-з'єднання.
За попередньою інформацією Android 16 вводить «permission expiration» для одноразових дозволів з автоматичним відкликанням через 24 години. Також очікується посилення вимог до фонової геолокації та розширення списку небезпечних дозволів для нових категорій (сенсори середовища, Wi-Fi сканування). Точні деталі з'являться у Q3 2027.
iOS не підтримує «звичайні дозволи» — кожен дозвіл запитується явно через системний діалог. Користувач може відкликати дозвіл у будь-який момент через налаштування. Основна відмінність — iOS попередньо не перевіряє статус дозволу через аналог checkSelfPermission: система автоматично показує діалог при першому зверненні до захищеного API.
Підсумки
POST_NOTIFICATIONS як runtime permission, Android 14 посилив вимоги до фонової геолокації.READ_EXTERNAL_STORAGE для вибору зображень.Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також