shouldShowRequestPermissionRationale — is een Android API-methode die de ontwikkelaar vertelt of hij een uitleg aan de gebruiker moet tonen voordat hij een gevaarlijke machtiging aanvraagt. Volgens Android Developer Reference, 2024, de rational-methode retourneert true als de gebruiker het verzoek eerder heeft afgewezen maar de vlag Never Ask Again niet heeft ingesteld. Dit is een essentieel instrument voor het bouwen van een vriendelijke UX bij het werken met runtime-machtigingen.
Belangrijkste
shouldShowRequestPermissionRationale — is een methode van de klassen Activity en Fragment in Android, beschikbaar via ActivityCompat voor compatibiliteit. Het ontvangt de naam van de machtiging en retourneert een Boolean die aangeeft of de gebruiker een extra uitleg moet krijgen voordat het verzoek wordt herhaald. De methode verscheen in Android 6.0 Marshmallow samen met het runtime-machtigingenmodel.
Het rationale-mechanisme is gebouwd op het volgen van de interactiegeschiedenis van de gebruiker met machtigingsdialoogvensters. Het systeem onthoudt of de gebruiker het verzoek eerder heeft afgewezen. Als de afwijzing plaatsvond zonder de vlag Never Ask Again in te stellen, retourneert shouldShowRequestPermissionRationale true. Dit is een signaal voor de ontwikkelaar: de gebruiker begrijpt niet waarom de machtiging nodig is en er is een extra uitleg vereist. Volgens Google Material Design Guidelines verhoogt het tonen van het rationale-dialoogvenster na de eerste weigering de kans op het opnieuw verlenen van de machtiging met 35 procent.
Het is belangrijk om de semantiek van de geretourneerde waarden te begrijpen: true betekent dat het zinvol is om het dialoogvenster te tonen, false — het dialoogvenster is niet nodig (de machtiging is al verleend of nooit aangevraagd) of is nutteloos (Never Ask Again is actief). De methode is geen garantie dat het dialoogvenster wordt getoond — het geeft slechts een aanbeveling. De ontwikkelaar beslist zelf welke UI hij als antwoord toont.
shouldShowRequestPermissionRationale werd geïntroduceerd in API Level 23 samen met een groep methoden voor runtime-machtigingen. Vóór Android 6.0 werden alle machtigingen bij installatie aangevraagd en was een uitlegmechanisme niet nodig — de gebruiker accepteerde of weigerde de hele lijst in één keer. Het runtime-model maakte de situatie mogelijk waarin de gebruiker het verzoek afwijst zonder de context te begrijpen en juist daarom is rationale nodig.
De logica van de methode is als volgt. Bij de eerste aanroep van requestPermissions voor een specifieke machtiging retourneert shouldShowRequestPermissionRationale false — de gebruiker is nog niet met het dialoogvenster geconfronteerd. Als de gebruiker het verzoek heeft afgewezen (op Deny heeft gedrukt), begint de methode true te retourneren. Na herhaalde afwijzing met de vlag Never Ask Again retourneert de methode false.
Volledige tabel van statussen:
| Status | shouldShowRationale | checkSelfPermission | Actie van de ontwikkelaar |
|---|---|---|---|
| Niet aangevraagd | false | DENIED | Systeemdialoog tonen |
| Verleend | false | GRANTED | Functie uitvoeren |
| Eerste keer geweigerd | true | DENIED | Rationale tonen, dan systeemdialoog |
| Never Ask Again | false | DENIED | Doorverwijzen naar Instellingen |
De combinatie shouldShowRequestPermissionRationale = false en checkSelfPermission = DENIED — is het moeilijkst te verwerken geval. Het betekent dat de machtiging nooit is aangevraagd of dat Never Ask Again is ingesteld. De ontwikkelaar moet deze twee statussen onderscheiden. De enige manier — het opslaan van de vlag firstRequest in SharedPreferences of het gebruik van SavedStateHandle. Stel bij het eerste verzoek de vlag in en als shouldShowRationale false retourneert en de vlag al true is — betekent dit Never Ask Again.
shouldShowRequestPermissionRationale wordt gereset wanneer de gebruiker de app verwijdert en opnieuw installeert, de app-gegevens wist of de machtigingsinstellingen reset. Na herinstallatie retourneert de methode weer false voor het eerste verzoek. Systeemupdates en het wijzigen van de Android-versie resetten de geschiedenis niet — deze wordt opgeslagen in de app-gegevens.
Correcte implementatie van rationale omvat drie componenten: controle van shouldShowRequestPermissionRationale na weigering, weergave van een aangepast dialoogvenster met uitleg en het opnieuw aanroepen van requestPermissions na een positief antwoord van de gebruiker. Het dialoogvenster moet beknopt, specifiek zijn en uitleggen waarom de app precies deze machtiging nodig heeft.
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("Waarom is toegang tot geolocatie nodig")
.setMessage(
"De app gebruikt geolocatie om locaties op de kaart te markeren" +
". Zonder deze machtiging" +
" werkt de functie niet."
)
.setPositiveButton("Toestaan") { _, _ ->
requestPermissionLauncher.launch(permission)
}
.setNegativeButton("Annuleren", null)
.show()
}
De beste praktijken van Material Design raden aan om een bottom sheet of inline-banner te gebruiken in plaats van een modaal dialoogvenster voor rationale. Een bottom sheet is minder opdringerig en geeft de gebruiker context. Een inline-element op het scherm (bijvoorbeeld een kaart met uitleg en een knop Toestaan) laat zien dat de functie niet beschikbaar is zonder de machtiging, maar blokkeert de rest van de interface niet.
De tekst van de rationale moet worden gelokaliseerd en aangepast aan de specifieke functie. Gebruik geen algemene zinnen zoals „Dit is nodig voor de werking van de app”. Geef concreet aan: „Voor het tonen van het weer bij u in de buurt” of „Voor het opslaan van foto’s in de galerij”. Volgens Google UX Research verhogen concrete uitleg de kans op het verlenen van de machtiging met 50 procent.
Het verschil tussen shouldShowRequestPermissionRationale = true (eerste weigering) en false bij DENIED (Never Ask Again) — is het cruciale punt bij het verwerken van machtigingen. In het eerste geval aarzelde de gebruiker en kan een extra uitleg hem overtuigen om toegang te verlenen. In het tweede — heeft de gebruiker een definitieve beslissing genomen en een herhaald systeemdialoogvenster zal alleen irritatie veroorzaken.
Het verwerkingsalgoritme na weigering moet er als volgt uitzien:
Het is belangrijk om de volgorde niet te verwarren: controleer eerst shouldShowRequestPermissionRationale, niet checkSelfPermission. checkSelfPermission retourneert in beide gevallen DENIED. Alleen shouldShowRequestPermissionRationale onderscheidt de eerste weigering van Never Ask Again. Gebruik SavedStateHandle of SharedPreferences om de vlag „erste verzoek is geweest” op te slaan — dit is de enige betrouwbare manier om „niet aangevraagd” van „geblokkeerd” te onderscheiden.
Toon rationale slechts één keer. Als de gebruiker het verzoek na de rationale opnieuw heeft afgewezen — toon dan geen uitleg meer. Ga direct over tot het voorstel om de instellingen te openen. Herhaaldelijk tonen van rationale wordt als opdringerig ervaren en verlaagt de beoordeling van de app. Optimale scenario: verzoek — weigering — rationale — herhaald verzoek — weigering — Instellingen.
Toon geen rationale vóór het eerste verzoek. Sommige ontwikkelaars tonen ten onrechte uitleg vóór het eerste dialoogvenster, met als argument dat „de gebruiker het moet begrijpen”. Dit verslechtert de UX: de gebruiker ziet twee dialoogvensters achter elkaar in plaats van één. Google raadt aan om het systeemdialoogvenster direct te tonen en rationale pas na weigering.
Gebruik contextuele rationale, gekoppeld aan het moment waarop de functie echt nodig is. Vraag niet alle machtigingen bij het starten van de app — dit is het laagste verleningspercentage. Vraag CAMERA wanneer de gebruiker op de knop „Foto maken” heeft gedrukt en LOCATION wanneer hij de kaart heeft geopend. Contextueel verzoek in combinatie met rationale verhoogt de verlening tot 80 procent tegenover 30 procent bij het initiële verzoek.
Testen van shouldShowRequestPermissionRationale vereist het controleren van vier statussen uit de tabel: niet aangevraagd, verleend, geweigerd, Never Ask Again. In eenheidstests wordt FakePermissionHandler met configureerbaar shouldShowRationale-gedrag gebruikt. In instrumentele tests — UiAutomator of Espresso met emulatie van antwoorden op systeemdialoogvensters.
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
)
}
}
Het belangrijkste scenario voor de instrumentele test — controleren of het rationale-dialoogvenster daadwerkelijk verschijnt na de eerste weigering. Gebruik Espresso met idling resources om te wachten op het systeemdialoogvenster, druk vervolgens op Deny, controleer het verschijnen van het aangepaste dialoogvenster met de uitlegtekst en druk op Allow — controleer de verlening. UIAutomator maakt interactie met het systeemdialoogvenster mogelijk via de knoptekst, wat de test stabieler maakt.
Het is ook de moeite waard om het scenario van weigering binnen het rationale-dialoogvenster te testen. Als de gebruiker op Deny heeft gedrukt in de aangepaste uitleg, zou shouldShowRequestPermissionRationale opnieuw true moeten retourneren, omdat Never Ask Again nog niet is geactiveerd. Beste praktijk — na twee opeenvolgende weigeringen direct doorverwijzen naar Instellingen om de gebruiker niet te irriteren met herhaalde uitleg en de beoordeling van de app niet te verlagen.
Veelgestelde vragen
true — als het verzoek eerder is afgewezen en Never Ask Again niet is ingesteld. false — als de machtiging niet is aangevraagd, is verleend of permanent is geblokkeerd. De combinatie false + DENIED vereist controle via een extra vlag.
Toon rationale alleen na de eerste weigering van de gebruiker, wanneer shouldShowRequestPermissionRationale true heeft geretourneerd. Vóór het eerste verzoek is rationale niet nodig — dit verslechtert de UX en creëert onnodige dialoogvensters.
Sla de vlag isFirstRequest op in SharedPreferences of SavedStateHandle. Als shouldShowRationale = false, checkSelfPermission = DENIED en de vlag = true — dan is Never Ask Again geactiveerd. Als de vlag = false — dit is het eerste verzoek.
Toon een dialoogvenster met de knop „Instellingen openen” die de gebruiker doorverwijst naar ACTION_APPLICATION_DETAILS_SETTINGS. Roep requestPermissions niet opnieuw aan — het dialoogvenster verschijnt niet en het resultaat komt met DENIED zonder bericht.
Gebruik in eenheidstests FakePermissionHandler met het configureerbare veld shouldShowRationale. In instrumentele tests — Espresso of UIAutomator met emulatie van het systeemdialoogvenster. Controleer alle 4 statussen uit de tabel.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook