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 се задава в системните дефиниции на разрешенията на ниво OS. Когато приложението декларира 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. След отговора системата извиква callback 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 и да тестват заявките на актуалните версии на OS.

Разрешения за 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, обработка на отказ. За Normal е достатъчен един ред в 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 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също