Dangerous Permission в Android: суть, список дозволів і runtime-запит

Автор: IT Sectr Опубліковано: 2026-05-20 Час читання: 8 хв

Dangerous Permission — це категорія дозволів в Android, які вимагають явної згоди користувача через runtime-діалог під час роботи застосунку. Згідно з Android Developer Guide, 2024, небезпечні дозволи мають ProtectionLevel dangerous і надають доступ до конфіденційних даних: камери, мікрофона, геолокації та контактів. Без явної згоди користувача застосунок не може використовувати ці функції.

Головне

  • Dangerous Permission — дозволи Android з ProtectionLevel dangerous, що вимагають runtime-запиту.
  • Запит виконується через ActivityCompat.requestPermissions з обробкою в onRequestPermissionsResult.
  • Користувач може відкликати небезпечний дозвіл у будь-який момент через Налаштування застосунку.
  • Перед запитом потрібно перевіряти статус через ContextCompat.checkSelfPermission.
  • Список включає CAMERA, RECORD_AUDIO, ACCESS_FINE_LOCATION, READ_CONTACTS та інші.

Що таке Dangerous Permission в Android

Dangerous Permission — це категорія системних дозволів Android, що надають доступ до конфіденційних даних користувача. На відміну від нормальних, небезпечні дозволи не видаються автоматично під час встановлення — застосунок повинен явно запитати їх під час виконання через runtime-механізм, представлений в Android 6.0 Marshmallow (API 23).

Необхідність явного запиту зумовлена характером даних, які захищають ці дозволи: геолокація користувача, особисті контакти, вміст камери та мікрофона, історія дзвінків та SMS. Android розглядає ці дані як чутливі і вимагає, щоб користувач свідомо надав доступ. За даними Android Privacy Sandbox (2024), користувачі відхиляють близько 30 відсотків runtime-запитів у середньому.

Ключова особливість Dangerous Permission — можливість відкликання в будь-який момент. Користувач може зайти в Налаштування — Застосунки — Дозволи і перемкнути тумблер для будь-якого небезпечного дозволу. Застосунок має бути готовий до того, що дозвіл, який було надано, може бути відкликано в будь-який момент без перезапуску.

ProtectionLevel dangerous

Рівень захисту dangerous задається в системних дефініціях дозволів на рівні ОС. Коли застосунок оголошує uses-permission з таким protectionLevel, система позначає дозвіл як такий, що вимагає runtime-запиту. На відміну від normal, dangerous-дозволи завжди відображаються в системному інтерфейсі керування дозволами і можуть бути відкликані.

Permission Group та Dangerous

Усі небезпечні дозволи згруповано в Permission Group за функціональною ознакою. Наприклад, CAMERA та CAMERA2 знаходяться в групі CAMERA, ACCESS_FINE_LOCATION та ACCESS_COARSE_LOCATION — в групі LOCATION. Якщо користувач надав один дозвіл із групи, інші дозволи тієї ж групи надаються автоматично без додаткового діалогу.

Як працює runtime-запит

Runtime-запит — це механізм, при якому застосунок викликає системний API для відображення діалогу із запитом дозволу. Користувач бачить модальне вікно з назвою дозволу та кнопками Allow і Deny. Після відповіді система викликає колбек onRequestPermissionsResult з результатом.

Повний цикл включає три кроки: перевірка статусу через checkSelfPermission, виклик requestPermissions за відсутності дозволу та обробка результату в onRequestPermissionsResult. Перевірка статусу обов'язкова, оскільки користувач міг відкликати дозвіл у будь-який момент через налаштування, і виклик функції без перевірки призведе до SecurityException.

kotlin
fun checkAndRequestCameraPermission() {
    when {
        ContextCompat.checkSelfPermission(
            this,
            Manifest.permission.CAMERA
        ) == PackageManager.PERMISSION_GRANTED -> {
            openCamera()
        }
        else -> {
            ActivityCompat.requestPermissions(
                this,
                arrayOf(Manifest.permission.CAMERA),
                REQUEST_CAMERA_CODE
            )
        }
    }
}

Обробка результату відбувається в ActivityResultLauncher або onRequestPermissionsResult. Рекомендований сучасний підхід — використання ActivityResultContracts.RequestPermission, який надає чистіший API без явних кодів запитів. Цей контракт повертає Boolean — чи надано дозвіл.

Найкращі практики запиту

Запитуйте небезпечні дозволи строго в контексті використання функції, а не під час запуску застосунку. Якщо користувач натиснув кнопку камери — запитуйте CAMERA. Якщо відкрив карту — запитуйте LOCATION. Контекстний запит дає вдвічі більше надань, ніж запит усіх дозволів при першому запуску. Також рекомендується запитувати не більше одного дозволу за раз, щоб користувач розумів, яка функція вимагає доступу.

Список небезпечних дозволів в Android

Android визначає кілька груп небезпечних дозволів, кожна з яких включає від однієї до кількох констант. Найбільш повний список представлений в класі Manifest.permission. Нижче наведено основні групи та дозволи, що використовуються в розробці.

Група Permission GroupДозволиAPI доступу
CAMERACAMERACamera API, CameraX
LOCATIONACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATIONFusedLocationProvider, Geofence
MICROPHONERECORD_AUDIOMediaRecorder, AudioRecord
PHONEREAD_PHONE_STATE, CALL_PHONE, READ_CALL_LOGTelephonyManager
CONTACTSREAD_CONTACTS, WRITE_CONTACTS, GET_ACCOUNTSContactsContract
SMSREAD_SMS, SEND_SMS, RECEIVE_SMSSmsManager
STORAGEREAD_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGEMediaStore, File API
CALENDARREAD_CALENDAR, WRITE_CALENDARCalendarContract

Нові дозволи в Android 12+

Починаючи з Android 12, Google посилив вимоги до деяких дозволів. Наприклад, BLUETOOTH_CONNECT та BLUETOOTH_SCAN стали небезпечними і вимагають runtime-запиту. Також з'явився дозвіл BODY_SENSORS_BACKGROUND для фонового доступу до датчиків. Розробникам необхідно оновлювати targetSdkVersion і тестувати запити на актуальних версіях ОС.

Дозволи для Android 13+

Android 13 (API 33) ввів нові дозволи для сповіщень (POST_NOTIFICATIONS) та медіа-файлів (READ_MEDIA_IMAGES, READ_MEDIA_VIDEO, READ_MEDIA_AUDIO), які замінили загальний READ_EXTERNAL_STORAGE. Тепер доступ до фото, відео та аудіо запитується окремо через спеціалізовані дозволи без єдиного діалогу.

Dangerous vs Normal Permission

Dangerous та Normal Permission принципово різняться за способом надання, можливістю відкликання та UX. Normal надається автоматично під час встановлення, Dangerous вимагає явного runtime-діалогу. Normal не можна відкликати через налаштування, Dangerous можна вимкнути в будь-який момент. Ця асиметрія закладає різні патерни розробки.

З точки зору коду, небезпечні дозволи вимагають більше роботи: checkSelfPermission, requestPermissions, обробка відмови. Для нормальних достатньо одного рядка в AndroidManifest.xml. При цьому Dangerous Permission дає користувачеві контроль, що підвищує довіру, особливо для чутливих функцій на кшталт камери або геолокації.

Вибір між категоріями не стоїть перед розробником — він визначається системою. Розробник лише оголошує uses-permission, а система на основі protectionLevel визначає категорію. Однак стратегія запиту небезпечних дозволів впливає на користувацький досвід: часті або недоречні діалоги знижують рейтинг застосунку.

Як запитувати дозволи в Kotlin

Сучасний спосіб запиту дозволів в Kotlin — використання ActivityResultContracts.RequestMultiplePermissions або RequestPermission. Ці контракти входять до бібліотеки androidx.activity і надають чистий API на основі лямбд, без необхідності перевизначати onRequestPermissionsResult.

kotlin
class CameraActivity : AppCompatActivity() {
    private val requestPermissionLauncher =
        registerForActivityResult(
            ActivityResultContracts.RequestPermission()
        ) { isGranted: Boolean ->
            if (isGranted) {
                openCamera()
            } else {
                showPermissionDeniedMessage()
            }
        }

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

Запит кількох дозволів одночасно

Коли застосунку потрібно кілька небезпечних дозволів одночасно, використовуйте RequestMultiplePermissions. Контракт повертає Map<String, Boolean>, де ключ — ім'я дозволу, значення — результат. Це зручно при першому запуску, коли потрібно запитати CAMERA та RECORD_AUDIO для відеозапису.

Обробка відмови вперше

Якщо користувач відхилив запит, метод shouldShowRequestPermissionRationale повертає true. Це сигнал показати пояснення, навіщо потрібен дозвіл. Найкраща практика — показувати кастомний діалог з поясненням та кнопкою Повторити. Якщо користувач повторно відхилив запит з позначкою Never Ask Again, shouldShowRequestPermissionRationale поверне false, і потрібно перенаправляти до Налаштувань.

Обробка відмови та Never Ask Again

Never Ask Again — це прапорець, який користувач може встановити при повторному відхиленні runtime-діалогу. Після цього стандартне діалогове вікно більше не показується для даного дозволу. Єдиний спосіб надати доступ — перенаправити користувача в системні налаштування застосунків.

Розробнику потрібно розрізняти два сценарії відмови: перший — коли shouldShowRequestPermissionRationale повертає true (користувач відхилив, але діалог ще можна показати), і другий — коли метод повертає false (Never Ask Again активний, або дозвіл заблоковано політикою). У другому випадку слід показувати кнопку Відкрити налаштування.

kotlin
fun handlePermissionDenied(permission: String) {
    if (ActivityCompat.shouldShowRequestPermissionRationale(
            this, permission
    )) {
        showRationaleDialog(permission)
    } else {
        showSettingsRedirectDialog(permission)
    }
}

private fun showSettingsRedirectDialog(permission: String) {
    AlertDialog.Builder(this)
        .setTitle("Доступ заборонено")
        .setMessage(
            "Дозвіл заблоковано. Відкрийте налаштування."
        )
        .setPositiveButton("Налаштування") { _, _ ->
            val intent = Intent(
                Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
                Uri.fromParts(
                    "package", packageName, null
                )
            )
            startActivity(intent)
        }
        .show()
}

Важливо не запитувати дозвіл повторно, якщо shouldShowRequestPermissionRationale повернув false. Повторний виклик requestPermissions у цьому випадку не покаже діалог — результат прийде миттєво з DENIED без пояснення. Користувач зіткнеться з незрозумілою поведінкою, що негативно позначиться на досвіді використання застосунку.

Часті запитання

Які дозволи вважаються небезпечними в Android?

До Dangerous Permission належать дозволи з ProtectionLevel dangerous: CAMERA, RECORD_AUDIO, ACCESS_FINE_LOCATION, READ_CONTACTS, READ_SMS, READ_CALENDAR та інші. Повний список доступний в класі Manifest.permission.

Як перевірити, чи надано небезпечний дозвіл?

Використовуйте ContextCompat.checkSelfPermission, передавши контекст та ім'я дозволу. Метод повертає PERMISSION_GRANTED або PERMISSION_DENIED. Перевірку потрібно виконувати перед кожним викликом API, що вимагає небезпечного дозволу.

Що таке Permission Group для небезпечних дозволів?

Permission Group об'єднує пов'язані небезпечні дозволи. Якщо користувач надав один дозвіл із групи, інші надаються автоматично. Наприклад, LOCATION включає ACCESS_FINE_LOCATION та ACCESS_COARSE_LOCATION.

Як обробити Never Ask Again?

Перевірте shouldShowRequestPermissionRationale після відмови. Якщо метод повернув false і дозвіл все ще не надано — активовано Never Ask Again. Перенаправте користувача до Налаштувань через Intent з ACTION_APPLICATION_DETAILS_SETTINGS.

Чи потрібні небезпечні дозволи на Android 13+?

Так, вони залишаються обов'язковими. На Android 13+ змінилися деякі дозволи: POST_NOTIFICATIONS стало окремим runtime-дозволом, а READ_EXTERNAL_STORAGE замінено на READ_MEDIA_IMAGES для точкового доступу до медіа-файлів.

Підсумки

  • Dangerous Permission — дозволи Android з ProtectionLevel dangerous, що вимагають явного runtime-запиту у користувача.
  • Механізм включає три кроки: checkSelfPermission, requestPermissions та onRequestPermissionsResult.
  • Користувач може відкликати небезпечний дозвіл у будь-який момент через системні налаштування.
  • Основні групи: CAMERA, LOCATION, MICROPHONE, PHONE, CONTACTS, SMS, STORAGE, CALENDAR.
  • ActivityResultContracts.RequestPermission — сучасний API для запиту в Kotlin без кодів запитів.
  • ShouldShowRequestPermissionRationale допомагає розрізняти першу відмову та Never Ask Again.
  • На Android 13+ з'явилися нові дозволи: POST_NOTIFICATIONS та READ_MEDIA_IMAGES замість STORAGE.

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також