Dangerous Permission je kategorie oprávnění v Androidu, která vyžadují výslovný souhlas uživatele prostřednictvím runtime dialogu během provozu aplikace. Podle Android Developer Guide, 2024 mají nebezpečná oprávnění ProtectionLevel dangerous a poskytují přístup k důvěrným údajům: kameře, mikrofonu, geolokaci a kontaktům. Bez výslovného souhlasu uživatele aplikace nemůže tyto funkce používat.
Hlavní body
Dangerous Permission je kategorie systémových oprávnění Androidu, která poskytují přístup k důvěrným údajům uživatele. Na rozdíl od normálních oprávnění se nebezpečná oprávnění nevydávají automaticky při instalaci — aplikace je musí výslovně vyžádat za běhu prostřednictvím runtime mechanismu představeného v Android 6.0 Marshmallow (API 23).
Potřeba výslovné žádosti vyplývá z povahy údajů, které tato oprávnění chrání: geolokace uživatele, osobní kontakty, obsah kamery a mikrofonu, historie hovorů a SMS. Android považuje tyto údaje za citlivé a vyžaduje informovaný souhlas uživatele. Podle Android Privacy Sandbox (2024) uživatelé v průměru odmítají přibližně 30 procent runtime žádostí.
Klíčovou vlastností Dangerous Permission je možnost odvolání kdykoli. Uživatel může přejít do Nastavení — Aplikace — Oprávnění a přepnout přepínač pro libovolné nebezpečné oprávnění. Aplikace musí být připravena na to, že udělené oprávnění může být kdykoli odvoláno bez restartu.
Úroveň ochrany dangerous je nastavena v systémových definicích oprávnění na úrovni OS. Když aplikace deklaruje uses-permission s takovým protectionLevel, systém označí oprávnění jako vyžadující runtime žádost. Na rozdíl od normal jsou dangerous oprávnění vždy zobrazena v systémovém UI správy oprávnění a mohou být odvolána.
Všechna nebezpečná oprávnění jsou seskupena do Permission Group podle funkčního znaku. Například CAMERA a CAMERA2 jsou ve skupině CAMERA, ACCESS_FINE_LOCATION a ACCESS_COARSE_LOCATION — ve skupině LOCATION. Pokud uživatel udělil jedno oprávnění ze skupiny, ostatní oprávnění stejné skupiny jsou udělena automaticky bez dalšího dialogu.
Runtime žádost je mechanismus, při kterém aplikace volá systémové API pro zobrazení dialogu s žádostí o oprávnění. Uživatel vidí modální okno s názvem oprávnění a tlačítky Allow a Deny. Po odpovědi systém zavolá callback onRequestPermissionsResult s výsledkem.
Celý cyklus zahrnuje tři kroky: kontrola stavu prostřednictvím checkSelfPermission, volání requestPermissions při absenci oprávnění a zpracování výsledku v onRequestPermissionsResult. Kontrola stavu je povinná, protože uživatel může oprávnění kdykoli odvolat prostřednictvím nastavení a volání funkce bez kontroly povede k SecurityException.
fun checkAndRequestCameraPermission() {
when {
ContextCompat.checkSelfPermission(
this,
Manifest.permission.CAMERA
) == PackageManager.PERMISSION_GRANTED -> {
openCamera()
}
else -> {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.CAMERA),
REQUEST_CAMERA_CODE
)
}
}
}
Zpracování výsledku probíhá v ActivityResultLauncher nebo onRequestPermissionsResult. Doporučený moderní přístup — použití ActivityResultContracts.RequestPermission, který poskytuje čistší API bez explicitních kódů žádosti. Tato smlouva vrací Boolean — zda bylo oprávnění uděleno či nikoli.
Žádejte nebezpečná oprávnění striktně v kontextu použití funkce, nikoli při spuštění aplikace. Pokud uživatel stiskl tlačítko kamery — žádejte CAMERA. Pokud otevřel mapu — žádejte LOCATION. Kontextuální žádost poskytuje dvakrát více souhlasů než žádost o všechna oprávnění při prvním spuštění. Rovněž se doporučuje nežádat o více než jedno oprávnění najednou, aby uživatel pochopil, která funkce vyžaduje přístup.
Android definuje několik skupin nebezpečných oprávnění, z nichž každá obsahuje jednu až několik konstant. Nejúplnější seznam je uveden ve třídě Manifest.permission. Níže jsou uvedeny hlavní skupiny a oprávnění používaná ve vývoji.
| Skupina Permission Group | Oprávnění | API přístupu |
|---|---|---|
| CAMERA | CAMERA | Camera API, CameraX |
| LOCATION | ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION | FusedLocationProvider, Geofence |
| MICROPHONE | RECORD_AUDIO | MediaRecorder, AudioRecord |
| PHONE | READ_PHONE_STATE, CALL_PHONE, READ_CALL_LOG | TelephonyManager |
| CONTACTS | READ_CONTACTS, WRITE_CONTACTS, GET_ACCOUNTS | ContactsContract |
| SMS | READ_SMS, SEND_SMS, RECEIVE_SMS | SmsManager |
| STORAGE | READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE | MediaStore, File API |
| CALENDAR | READ_CALENDAR, WRITE_CALENDAR | CalendarContract |
Od Android 12 Google zpřísnil požadavky na některá oprávnění. Například BLUETOOTH_CONNECT a BLUETOOTH_SCAN se staly nebezpečnými a vyžadují runtime žádost. Také se objevilo oprávnění BODY_SENSORS_BACKGROUND pro přístup na pozadí k senzorům. Vývojáři musí aktualizovat targetSdkVersion a testovat žádosti na aktuálních verzích OS.
Android 13 (API 33) zavedl nová oprávnění pro oznámení (POST_NOTIFICATIONS) a pro mediální soubory (READ_MEDIA_IMAGES, READ_MEDIA_VIDEO, READ_MEDIA_AUDIO), která nahradila obecné READ_EXTERNAL_STORAGE. Nyní se přístup k fotkám, videím a audiu žádá samostatně prostřednictvím specializovaných oprávnění bez jediného dialogu.
Dangerous a Normal Permission se zásadně liší způsobem udělení, možností odvolání a UX. Normal se uděluje automaticky při instalaci, Dangerous vyžaduje explicitní runtime dialog. Normal nelze odvolat prostřednictvím nastavení, Dangerous lze kdykoli vypnout. Tato asymetrie vytváří různé vývojové vzory.
Z hlediska kódu vyžadují nebezpečná oprávnění více práce: checkSelfPermission, requestPermissions, zpracování odmítnutí. Pro Normální stačí jeden řádek v AndroidManifest.xml. Zároveň Dangerous Permission dává uživateli kontrolu, což zvyšuje důvěru, zejména u citlivých funkcí, jako je kamera nebo geolokace.
Volba mezi kategoriemi nestojí před vývojářem — je určena systémem. Vývojář pouze deklaruje uses-permission a systém na základě protectionLevel určuje kategorii. Nicméně strategie žádosti o nebezpečná oprávnění ovlivňuje uživatelský zážitek: časté nebo nevhodné dialogy snižují hodnocení aplikace.
Moderní způsob žádosti o oprávnění v Kotlinu — použití ActivityResultContracts.RequestMultiplePermissions nebo RequestPermission. Tyto smlouvy jsou součástí knihovny androidx.activity a poskytují čisté API založené na lambdách, bez nutnosti přepisovat onRequestPermissionsResult.
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
)
}
}
}
Když aplikace potřebuje několik nebezpečných oprávnění současně, použijte RequestMultiplePermissions. Smlouva vrací Map<String, Boolean>, kde klíč je název oprávnění a hodnota je výsledek. To je vhodné při prvním spuštění, když je potřeba požádat o CAMERA a RECORD_AUDIO pro nahrávání videa.
Pokud uživatel žádost odmítl, metoda shouldShowRequestPermissionRationale vrací true. To je signál k zobrazení vysvětlení, proč je oprávnění potřeba. Nejlepším postupem je zobrazení vlastního dialogu s vysvětlením a tlačítkem Zkusit znovu. Pokud uživatel znovu odmítl žádost se zaškrtnutím Never Ask Again, shouldShowRequestPermissionRationale vrátí false a je třeba přesměrovat do Nastavení.
Never Ask Again je příznak, který může uživatel nastavit při opětovném odmítnutí runtime dialogu. Poté se standardní dialogové okno pro toto oprávnění již nezobrazí. Jediný způsob, jak poskytnout přístup — přesměrování uživatele do systémového nastavení aplikací.
Vývojář musí rozlišovat dva scénáře odmítnutí: první — když shouldShowRequestPermissionRationale vrací true (uživatel odmítl, ale dialog lze ještě zobrazit) a druhý — když metoda vrací false (Never Ask Again je aktivní nebo je oprávnění blokováno politikou). V druhém případě je třeba zobrazit tlačítko Otevřít nastavení.
fun handlePermissionDenied(permission: String) {
if (ActivityCompat.shouldShowRequestPermissionRationale(
this, permission
)) {
showRationaleDialog(permission)
} else {
showSettingsRedirectDialog(permission)
}
}
private fun showSettingsRedirectDialog(permission: String) {
AlertDialog.Builder(this)
.setTitle("Přístup odepřen")
.setMessage(
"Oprávnění je zablokováno. Otevřete nastavení."
)
.setPositiveButton("Nastavení") { _, _ ->
val intent = Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts(
"package", packageName, null
)
)
startActivity(intent)
}
.show()
}
Je důležité nežádat o oprávnění znovu, pokud shouldShowRequestPermissionRationale vrátil false. Opakované volání requestPermissions v tomto případě nezobrazí dialog — výsledek přijde okamžitě s DENIED bez vysvětlení. Uživatel narazí na nepochopitelné chování, což negativně ovlivní zážitek z používání aplikace.
Často kladené otázky
Mezi Dangerous Permission patří oprávnění s ProtectionLevel dangerous: CAMERA, RECORD_AUDIO, ACCESS_FINE_LOCATION, READ_CONTACTS, READ_SMS, READ_CALENDAR a další. Úplný seznam je k dispozici ve třídě Manifest.permission.
Použijte ContextCompat.checkSelfPermission s předáním kontextu a názvu oprávnění. Metoda vrací PERMISSION_GRANTED nebo PERMISSION_DENIED. Kontrola by měla být provedena před každým voláním API, které vyžaduje nebezpečné oprávnění.
Permission Group sdružuje související nebezpečná oprávnění. Pokud uživatel udělil jedno oprávnění ze skupiny, ostatní jsou udělena automaticky. Například LOCATION zahrnuje ACCESS_FINE_LOCATION a ACCESS_COARSE_LOCATION.
Zkontrolujte shouldShowRequestPermissionRationale po odmítnutí. Pokud metoda vrátila false a oprávnění stále není uděleno — je aktivován Never Ask Again. Přesměrujte uživatele do Nastavení prostřednictvím Intent s ACTION_APPLICATION_DETAILS_SETTINGS.
Ano, zůstávají povinná. Na Android 13+ se některá oprávnění změnila: POST_NOTIFICATIONS se stalo samostatným runtime oprávněním a READ_EXTERNAL_STORAGE bylo nahrazeno READ_MEDIA_IMAGES pro přesný přístup k mediálním souborům.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také