shouldShowRequestPermissionRationale — egy Android API metódus, amely jelzi a fejlesztőnek, hogy meg kell-e jelenítenie egy magyarázatot a felhasználó számára egy veszélyes engedély kérése előtt. A Android Developer Reference, 2024 szerint a rational metódus true értéket ad vissza, ha a felhasználó korábban elutasította a kérést, de nem állította be a Never Ask Again jelzőt. Ez egy kulcsfontosságú eszköz az udvarias UX felépítéséhez futásidő engedélyekkel való munka során.
Főbb pontok
shouldShowRequestPermissionRationale — egy metódus az Activity és Fragment osztályokban Androidban, amely az ActivityCompat-on keresztül érhető el a kompatibilitás érdekében. Fogadja az engedély nevét és egy Boolean értéket ad vissza, jelezve, hogy meg kell-e jeleníteni egy további magyarázatot a felhasználó számára az ismételt kérés előtt. A metódus az Android 6.0 Marshmallow-ban jelent meg a futásidő engedélymodell részeként.
A rationale mechanizmus a felhasználó és az engedély párbeszédek közötti interakció történetének nyomon követésére épül. A rendszer emlékszik, hogy a felhasználó korábban elutasította-e a kérést. Ha az elutasítás a Never Ask Again jelző beállítása nélkül történt, a shouldShowRequestPermissionRationale true értéket ad vissza. Ez egy jelzés a fejlesztő számára: a felhasználó nem érti, miért van szükség az engedélyre, és további magyarázat szükséges. A Google Material Design Guidelines szerint a rationale párbeszéd megjelenítése az első elutasítás után 35 százalékkal növeli az engedély újboli megadásának valószínűségét.
Fontos megérteni a visszaadott értékek szemantikáját: a true azt jelenti, hogy van értelme megjeleníteni a párbeszédet, a false — a párbeszéd nem szükséges (az engedély már meg van adva, vagy soha nem kérték), vagy hasztalan (a Never Ask Again aktív). A metódus nem garancia arra, hogy a párbeszéd megjelenik — csak ajánlást ad. A fejlesztő maga dönti el, hogy válaszként milyen UI-t jelenít meg.
A shouldShowRequestPermissionRationale az API Level 23-ban került bevezetésre a futásidő engedélyek metóduscsoportjával együtt. Az Android 6.0 előtt minden engedélyt telepítéskor kértek, és nem volt szükség magyarázó mechanizmusra — a felhasználó a teljes listát egyszerre fogadta el vagy utasította el. A futásidő modell lehetővé tette azt a helyzetet, amikor a felhasználó a kontextus megértése nélkül utasítja el a kérést, és pontosan ezért van szükség a rationale-ra.
A metódus logikája a következő. A requestPermissions első meghívásakor egy adott engedélyre a shouldShowRequestPermissionRationale false értéket ad vissza — a felhasználó még nem találkozott a párbeszéddel. Ha a felhasználó elutasította a kérést (megnyomta a Deny gombot), a metódus true értéket kezd visszaadni. A Never Ask Again jelzővel történő ismételt elutasítás után a metódus false értéket ad vissza.
Az állapotok teljes táblázata:
| Állapot | shouldShowRationale | checkSelfPermission | Fejlesztői művelet |
|---|---|---|---|
| Nem kérték | false | DENIED | Rendszer párbeszéd megjelenítése |
| Megadták | false | GRANTED | Funkció végrehajtása |
| Első alkalommal elutasítva | true | DENIED | Rationale megjelenítése, majd rendszer párbeszéd |
| Never Ask Again | false | DENIED | Átirányítás a Beállításokhoz |
A shouldShowRequestPermissionRationale = false és a checkSelfPermission = DENIED kombinációja — a legnehezebben feldolgozható eset. Azt jelenti, hogy az engedélyt soha nem kérték, vagy a Never Ask Again be van állítva. A fejlesztőnek meg kell különböztetnie ezt a két állapotot. Az egyetlen mód — a firstRequest jelző tárolása SharedPreferences-ben vagy a SavedStateHandle használata. Az első kérésnél állítsa be a jelzőt, és ha a shouldShowRationale false értéket ad vissza, és a jelző már true — ez Never Ask Again-t jelent.
A shouldShowRequestPermissionRationale visszaállítódik, ha a felhasználó eltávolítja és újratelepíti az alkalmazást, törli az alkalmazás adatait, vagy visszaállítja az engedélybeállításokat. Újratelepítés után a metódus ismét false értéket ad vissza az első kérésre. A rendszerfrissítések és az Android verzióváltás nem állítják vissza a történetet — az az alkalmazás adataiban tárolódik.
A helyes implementáció három összetevőt foglal magában: a shouldShowRequestPermissionRationale ellenőrzését az elutasítás után, egy egyedi párbeszédablak megjelenítését magyarázattal, és a requestPermissions újboli meghívását a felhasználó pozitív válasza után. A párbeszédnek tömörnek, konkrétnak kell lennie, és meg kell magyaráznia, miért van szüksége az alkalmazásnak pont erre az engedélyre.
private fun requestLocationWithRationale() {
val permission = Manifest.permission.ACCESS_FINE_LOCATION
when {
ContextCompat.checkSelfPermission(
this, permission
) == PackageManager.PERMISSION_GRANTED -> {
startLocationTracking()
}
ActivityCompat.shouldShowRequestPermissionRationale(
this, permission
) -> {
showRationaleDialog(permission)
}
else -> {
requestPermissionLauncher.launch(permission)
}
}
}
private fun showRationaleDialog(
permission: String
) {
AlertDialog.Builder(this)
.setTitle("Miért van szükség a helymeghatározáshoz való hozzáférésre")
.setMessage(
"Az alkalmazás helymeghatározást használ a helyek térképen történő megjelölésére" +
". Ezen engedély nélkül" +
" a funkció nem fog működni."
)
.setPositiveButton("Engedélyez") { _, _ ->
requestPermissionLauncher.launch(permission)
}
.setNegativeButton("Mégse", null)
.show()
}
A Material Design legjobb gyakorlatai a bottom sheet vagy inline banner használatát javasolják a modális párbeszéd helyett a rationale számára. A bottom sheet kevésbé tolakodó és kontextust ad a felhasználónak. Az inline elem a képernyőn (például egy kártya magyarázattal és Engedélyez gombbal) azt mutatja, hogy a funkció engedély nélkül nem érhető el, de nem blokkolja a többi interfészt.
A rationale szövegét lokalizálni kell és az adott funkcióhoz kell igazítani. Ne használjon általános kifejezéseket, mint például „Ez az alkalmazás működéséhez szükséges”. Adja meg konkrétan: „Az Ön környékén lévő időjárás megjelenítéséhez” vagy „A fényképek galériába mentéséhez”. A Google UX Research szerint a konkrét magyarázatok 50 százalékkal növelik az engedély megadásának valószínűségét.
A különbség a shouldShowRequestPermissionRationale = true (első elutasítás) és a false DENIED esetén (Never Ask Again) között — kulcsfontosságú pont az engedélyek feldolgozásában. Az első esetben a felhasználó táprengett, és egy további magyarázat meggyőzheti a hozzáférés megadásáról. A második esetben — a felhasználó végleges döntést hozott, és az ismételt rendszer párbeszéd csak irritációt vált ki.
Az elutasítás utáni feldolgozási algoritmusnak így kell kinéznie:
Fontos, hogy ne keverje össze a sorrendet: először a shouldShowRequestPermissionRationale-t ellenőrizze, ne a checkSelfPermission-t. A checkSelfPermission mindkét esetben DENIED értéket ad vissza. Csak a shouldShowRequestPermissionRationale különbözteti meg az első elutasítást a Never Ask Again-től. Használja a SavedStateHandle vagy SharedPreferences-t az „első kérés megtörtént” jelző tárolására — ez az egyetlen megbízható mód a „nem kérték” és a „blokkolva” megkülönböztetésére.
Csak egyszer jelenítse meg a rationale-t. Ha a felhasználó a rationale után újra elutasította a kérést — ne jelenítsen meg többé magyarázatot. Közvetlenül térjen át a beállítások megnyitásának javaslatára. A rationale többszöri megjelenítése tolakodónak számít és csökkenti az alkalmazás értékelését. Optimális forgatókönyv: kérés — elutasítás — rationale — újra kérés — elutasítás — Beállítások.
Ne jelenítse meg a rationale-t az első kérés előtt. Néhány fejlesztő tévesen magyarázatot jelenít meg az első párbeszéd előtt, azzal érvelve, hogy „a felhasználónak meg kell értenie”. Ez rontja az UX-t: a felhasználó egy helyett két egymás utáni párbeszédet lát. A Google azt ajánlja, hogy a rendszer párbeszédet azonnal, a rationale-t pedig csak az elutasítás után jelenítse meg.
Használjon kontextuális rationale-t, amely ahhoz a pillanathoz kötődik, amikor a funkció tényleg szükséges. Ne kérjen minden engedélyt az alkalmazás indításakor — ez a legalacsonyabb megadási arány. Kérjen CAMERA-t, amikor a felhasználó megnyomta a „Fotózás” gombot, és LOCATION-t, amikor megnyitotta a térképet. A kontextuális kérés a rationale-nal kombinálva 80 százalékra növeli a megadást, szemben a kezdeti kérés 30 százalékával.
A shouldShowRequestPermissionRationale tesztelése a táblázat négy állapotának ellenőrzését igényli: nem kérték, megadták, elutasították, Never Ask Again. Az egységtesztekben FakePermissionHandler használható konfigurálható shouldShowRationale viselkedéssel. Az instrumentális tesztekben — UiAutomator vagy Espresso a rendszer párbeszédekre adott válaszok emulálásával.
class RationaleViewModelTest {
private val handler = FakePermissionHandler()
private val viewModel = PermissionsViewModel(handler)
fun testFirstDenial_shouldShowRationale() {
handler.shouldShowRationale = true
handler.cameraResult =
PermissionResult.DENIED(true)
viewModel.onCameraRequested()
assertEquals(
PermissionUiState.Denied(true),
viewModel.uiState.value
)
}
fun testNeverAskAgain_redirectToSettings() {
handler.shouldShowRationale = false
handler.cameraResult =
PermissionResult.DENIED(false)
viewModel.onCameraRequested()
assertEquals(
PermissionUiState.RedirectToSettings,
viewModel.uiState.value
)
}
}
A kulcsfontosságú forgatókönyv az instrumentális teszthez — annak ellenőrzése, hogy a rationale párbeszéd tényleg megjelenik-e az első elutasítás után. Használjon Espresso-t idling resources-szal a rendszer párbeszéd várakozásához, majd nyomja meg a Deny-t, ellenőrizze az egyedi párbeszéd megjelenését a magyarázó szöveggel és nyomja meg az Allow-t — ellenőrizze a megadást. Az UIAutomator lehetővé teszi a rendszer párbeszéddel való interakciót a gomb szövege alapján, ami stabilabbá teszi a tesztet.
Érdemes tesztelni az elutasítás forgatókönyvét a rationale párbeszéden belül is. Ha a felhasználó megnyomta a Deny-t az egyedi magyarázatban, a shouldShowRequestPermissionRationale-nak újra true értéket kell visszaadnia, mert a Never Ask Again még nem aktiválódott. Legjobb gyakorlat — két egymás utáni elutasítás után közvetlenül átirányítani a Beállításokhoz, hogy ne irritálja a felhasználót ismételt magyarázatokkal és ne csökkentse az alkalmazás értékelését.
Gyakran ismételt kérdések
true — ha a kérést korábban elutasították és a Never Ask Again nincs beállítva. false — ha az engedélyt nem kérték, megadták, vagy örökre blokkolva van. A false + DENIED kombináció egy további jelző segítségével történő ellenőrzést igényel.
Csak a felhasználó első elutasítása után jelenítse meg a rationale-t, amikor a shouldShowRequestPermissionRationale true értéket adott vissza. Az első kérés előtt a rationale nem szükséges — ez rontja az UX-t és felesleges párbeszédeket hoz létre.
Tárolja az isFirstRequest jelzőt SharedPreferences-ben vagy SavedStateHandle-ban. Ha shouldShowRationale = false, checkSelfPermission = DENIED és a jelző = true — akkor a Never Ask Again aktiválódott. Ha a jelző = false — ez az első kérés.
Jelenítsen meg egy párbeszédet a „Beállítások megnyitása” gombbal, amely átirányítja a felhasználót a ACTION_APPLICATION_DETAILS_SETTINGS címre. Ne hívja újra a requestPermissions-t — a párbeszéd nem jelenik meg, és az eredmény üzenet nélkül érkezik DENIED-ként.
Az egységtesztekben használjon FakePermissionHandler-t konfigurálható shouldShowRationale mezővel. Az instrumentális tesztekben — Espresso-t vagy UIAutomator-t a rendszer párbeszéd emulálásával. Ellenőrizze mind a 4 állapotot a táblázatból.
Összefoglaló
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is