IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 1 - Android - Úvod do oprávnění aplikací

Vítejte v Android kurzu, ve kterém si vysvětlíme problematiku udělování oprávnění (permissions) našim aplikacím. Budeme se věnovat zejména těm pro zařízení s verzí API 23 a vyšší, kde je nutné oprávnění udělovat při běhu aplikace a již nejsou udělena automaticky systémem při instalaci. Máme tedy novou problematiku, kterou se musíme jako Android vývojáři zabývat, aby naše aplikace uživatelům nepadaly na výjimku SecurityException.

Oprávnění

Účelem oprávnění je ochrana soukromí uživatele. Žádná aplikace ve výchozím nastavení nemá oprávnění provádět žádné operace, které mohou potenciálně nepříznivě ovlivnit jiné aplikace, operační systém nebo uživatele. Systém některá oprávnění uděluje automaticky a jiná až po souhlasu uživatele v závislosti na závažnosti daného oprávnění.

Kategorie oprávnění

Android dělí oprávnění do dvou kategorií dle závažnosti:

  • Normální oprávnění - Nepředstavují velké riziko pro soukromí uživatele nebo pro provoz zařízení.
  • Nebezpečná oprávnění - Musí udělit aplikaci uživatel a mohla by potenciálně ohrozit soukromí uživatele nebo normální provoz zařízení. Dokud uživatel oprávnění neudělí, aplikace nemůže poskytovat funkce, které na tomto oprávnění závisí.

Deklarace oprávnění

Každá aplikace musí požadovaná oprávnění (normální i nebezpečná společně) deklarovat v úvodní části souboru AndroidManifest.xml.

Příklad deklarace požadovaných oprávnění v manifestu by vypadal např. takto:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Uvedený příklad vyžaduje tato oprávnění:

  • Přístup k fotoaparátu (kameře)
  • Oprávnění k přímému vytáčení telefonních hovorů
  • Přístup k přesné poloze zařízení

Udělení normálních oprávnění

Ta oprávnění z deklarace v manifestu, která patří do kategorie normálních oprávnění, aplikace od systému získá během instalace do zařízení bez interakce s uživatelem. Zde tedy není moc co řešit :)

Udělení nebezpečných oprávnění

Nebezpečná deklarovaná oprávnění jsou udělována až na základě souhlasu uživatele. Způsob, jakým systém Android tento souhlas získá, závisí na verzi systému Android konkrétního zařízení:

  • Android 6.0 Marshmallow (API úroveň 23) a vyšší - Uživatel není v době instalace upozorněn na žádná požadovaná oprávnění. Požádán bude až za běhu aplikace ve chvíli, kdy aplikace bude chtít provádět činnost, která dané oprávnění vyžaduje.
  • Android 5.1.1 Lollipop (API úroveň 22) nebo nižší - Systém Android automaticky požádá uživatele o udělení všech deklarovaných nebezpečných oprávnění již při instalaci aplikace do zařízení. Pokud uživatel klikne na tlačítko Přijmout, všechna oprávnění jsou udělena v jednom okamžiku. Pokud uživatel žádost o oprávnění zamítne, je instalace aplikace ukončena. Pokud aktualizace aplikace vyžaduje další oprávnění, je uživatel vyzván k přijetí těchto nových oprávnění.

My se samozřejmě budeme zabývat tím novým způsobem, tedy od API úrovně 23. V kurzu budeme používat ukázkovou aplikaci Permissions, kterou si představíme později. Obrázky zde budou právě z ní.

Příklad - Základní postup pro udělení oprávnění

Nyní si popíšeme to nejnutnější povinné minimum, které musíme znát, abychom s oprávněními mohli pracovat. Tento postup také ale zároveň obsahuje úplné minimum informací pro uživatele. Jako příklad nám poslouží žádost o udělení oprávnění k přístupu ke kameře zařízení.

Krok 1 - Máme již oprávnění?

Prvním krokem je test, zda již nemá aplikace potřebné oprávnění uděleno. Tato kontrola musí proběhnout ještě před tím, než se aplikace pokusí o přístup ke kameře. Samotný obslužný kód kontroly oprávnění vypadá takto:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    if (checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
        // Oprávnění již bylo uděleno
        // Práce s kamerou zařízení
    } else {
        ActivityCompat.requestPermissions(
                    MainActivity.this,
                    new String[]{Manifest.permission.CAMERA},
                    PERMISSION_MINIMAL_REQUEST);
    }
}

Celý proces začíná testem, zda aplikace běží na verzi API 23 nebo vyšší. Pokud je verze API nižší než 23, není provedeno nic (protože uživatel oprávnění již udělil při instalaci). V opačném případě je volána metoda checkSelfPermission(), která otestuje, zda aplikace disponuje oprávněním, jehož název přijímá v parametru. Výsledkem bude vrácená hodnota typu int, která může nabývat hodnoty konstant:

  • PERMISSION_GRANTED (oprávnění uděleno) - Je-li oprávnění uděleno (podmínka je splněna), může být proveden kód přistupující ke kameře zařízení.
  • PERMISSION_DENIED (oprávnění odepřeno). Při zjištění, že oprávnění uděleno není, je volána metoda requestPermissions().

Krok 2 - Zažádání o oprávnění

Pokud oprávnění nemáme, tak o něj zažádáme. Metoda requestPermissions() má 3 parametry:

  • aktuální kontext
  • pole s názvy požadovaných oprávnění, můžeme tedy žádat o více najednou
  • hodnota typu int, sloužící jako poznávací značka pro pozdější zpracování odpovědi v přepsané metodě onRequestPermissionsResult() - podobně jako requestCode při otevírání dalších aktivit.

Voláním requestPermissions() požádáme o zobrazení systémového dialogového okna s žádostí o udělení konkrétního oprávnění:

Oprávnění Android aplikací

Krok 3 - Reakce na volbu uživatele

Jakmile uživatel zareaguje, systém nám zavolá metodu onRequestPermissionsResult(), kde zjistíme, zda nám uživatel oprávnění udělil či nikoli. Na základě toho tedy potenciálně nebezpečnou funkčnost v aplikaci buď budeme používat, nebo ji nesmíme spustit, jinak by naše aplikace spadla, viz dále.

Pokud uživatel udělení oprávnění v minulosti definitivně zamítl, dialog mu již znovu zobrazen nebude. V tomto případě zavolání metody requestPermissions() povede jen k automatickému přijetí odpovědi PERMISSION_DENIED v přepsané metodě onRequestPermissionsResult().

Přepsaná metoda pro zpracování odpovědi může vypadat takto:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        // Uživatel oprávnění udělil
        // Provedení akce, vyžadující udělené oprávnění
    }
}

S voláním uvedené metody získáme tři parametry:

  • requestCode - Toto je ona hodnota parametru requestCode metody requestPermissions(), kterou jsme si sem poslali při požadavku o udělení oprávnění. Díky této hodnotě poznáme, ze které části kódu tento požadavek pochází.
  • permissions - Pole textových řetězců s oprávněními, o jejichž udělení bylo požádáno. Jejich pořadí v poli odpovídá tomu pořadí, v jakém byly uvedeny při volání metody requestPermissions().
  • grantResults - Pole s odpověďmi na žádosti o udělení oprávnění, jejichž pořadí odpovídá pořadí pole v proměnné permissions.

Pokud uživatel v zobrazeném dialogovém okně stiskne tlačítko Odmítnout, bude okno zavřeno a požadovaná akce s fotoaparátem nebude provedena.

Definitivní zamítnutí

Dojde-li k dalšímu vyzvání uživatele k udělení oprávnění, bude zobrazeno takovéto okno:

Oprávnění Android aplikací

Oproti prvnímu dialogovému oknu navíc obsahuje zaškrtávací políčko Příště se neptat. Je-li toto políčko zaškrtnuto při dalším odmítnutí udělení oprávnění, bere systém na vědomí, že si již uživatel nepřeje být dotazován, zda toto konkrétní oprávnění udělí - a to ani v případě dalšího pokusu aplikace toto oprávnění získat. Nebude tedy dostupná ta funkce aplikace, která zamítnutá oprávnění vyžaduje.

Zrušení zamítnutí

Pokud by si své rozhodnutí uživatel rozmyslel a oprávnění chtěl dodatečně udělit, musí tak učinit poměrně komplikovanou cestou. V nastavení telefonu v seznamu nainstalovaných aplikací zobrazí detail konkrétní aplikace:

Oprávnění Android aplikací

Zobrazí položku Oprávnění:

Oprávnění Android aplikací

A zde nalezne seznam všech nebezpečných oprávnění, která aplikace požaduje v souboru manifestu. Jednotlivá oprávnění lze udělit nebo odepřít nastavením přepínače.

Jak je vidět, i když uživatel udělí aplikaci požadovaná oprávnění, nemůžeme se nikdy spolehnout na to, že toto oprávnění bude aplikace mít na vždy a je nutné, před každým přístupem k funkci zařízení, vyžadující oprávnění, za běhu aplikace kontrolovat, zda je oprávnění stále uděleno. Jinak by naše aplikace spadla na výjimku SecurityException.

Ošetření žádosti o udělení oprávnění od uživatele je povinné pro verze API 23 a vyšší a Android Studio se nás na tuto skutečnost snaží v kódu upozornit. To se děje, když se snažíme v kódu přistupovat k těm funkcím, které vyžadují udělení nebezpečných oprávnění.

Nevýhody základního postupu pro získání oprávnění

Popsaný postup dodatečného udělení oprávnění v nastavení zařízení nemusí běžný uživatel znát. Může se stát, že požadovaná oprávnění definitivně zamítne, aniž by si v tu chvíli plně uvědomoval následky, co se funkčnosti aplikace týče. Když již nebude žádost o udělení oprávnění zobrazována, daná funkce nebude dostupná a uživatel získá dojem, že aplikace nefunguje, na Google Play vaší aplikaci negativně ohodnotí a nakonec jí ze svého zařízení odinstaluje.

Proto je více než dobré popsaný základní postup získání oprávnění rozšířit tak, aby byl uživatel dostatečně informován. S tímto rozšířeným postupem se seznámíme dále v kurzu.

V příští lekci, Android - Spolehlivější postup pro získání oprávnění, se naučíme, jak přimět uživatele dát naší Android aplikaci potřebná oprávnění s mnohem vyšší pravděpodobností, než jen s normální žádostí.


 

Všechny články v sekci
Oprávnění Android aplikací
Přeskočit článek
(nedoporučujeme)
Android - Spolehlivější postup pro získání oprávnění
Článek pro vás napsal Pavel
Avatar
Uživatelské hodnocení:
2 hlasů
Autor se věnuje programování v Javě, hlavně pro Android. Mezi jeho další zájmy patří Arduino, Minecraft.
Aktivity