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-разрешения всегда отображаются в системном UI управления разрешениями и могут быть отозваны.

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, и нужно перенаправлять в Settings.

Обработка отказа и 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. Перенаправьте пользователя в Settings через 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 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

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