shouldShowRequestPermissionRationale ist eine Methode der Android-API, die dem Entwickler mitteilt, ob dem Benutzer vor der Anforderung einer gefährlichen Berechtigung eine Erklärung angezeigt werden soll. Laut der Android Developer Reference, 2024 gibt die Methode true zurück, wenn der Benutzer die Anfrage zuvor abgelehnt, aber das Never Ask Again-Flag nicht gesetzt hat. Dies ist ein wichtiges Werkzeug für eine benutzerfreundliche UX bei der Arbeit mit Laufzeitberechtigungen.
Wichtige Punkte
shouldShowRequestPermissionRationale ist eine Methode der Activity- und Fragment-Klassen in Android, die über ActivityCompat für Kompatibilität verfügbar ist. Sie nimmt einen Berechtigungsnamen entgegen und gibt einen Boolean zurück, der angibt, ob dem Benutzer vor einer erneuten Anfrage eine zusätzliche Erklärung angezeigt werden soll. Die Methode wurde in Android 6.0 Marshmallow zusammen mit dem Laufzeitberechtigungsmodell eingeführt.
Der Begründungsmechanismus basiert auf der Verfolgung des Interaktionsverlaufs des Benutzers mit Berechtigungsdialogen. Das System merkt sich, ob der Benutzer die Anfrage zuvor abgelehnt hat. Wenn die Ablehnung ohne Setzen des Never Ask Again-Flags erfolgte, gibt shouldShowRequestPermissionRationale true zurück. Dies ist ein Signal an den Entwickler: Der Benutzer versteht nicht, warum die Berechtigung benötigt wird, und eine zusätzliche Erklärung ist erforderlich. Laut den Google Material Design-Richtlinien erhöht die Anzeige eines Begründungsdialogs nach der ersten Ablehnung die Wahrscheinlichkeit einer erneuten Berechtigungserteilung um 35 Prozent.
Es ist wichtig, die Semantik der Rückgabewerte zu verstehen: true bedeutet, dass die Anzeige des Dialogs sinnvoll ist, false bedeutet, dass der Dialog entweder nicht benötigt wird (Berechtigung bereits erteilt oder nie angefordert) oder nutzlos ist (Never Ask Again aktiv). Die Methode ist keine Garantie dafür, dass der Dialog angezeigt wird — sie gibt nur eine Empfehlung. Der Entwickler entscheidet, welche UI als Antwort angezeigt wird.
shouldShowRequestPermissionRationale wurde auf API-Level 23 zusammen mit einer Gruppe von Methoden für Laufzeitberechtigungen eingeführt. Vor Android 6.0 wurden alle Berechtigungen bei der Installation angefordert, und es war kein Erklärungsmechanismus erforderlich — der Benutzer akzeptierte oder lehnte die gesamte Liste auf einmal ab. Das Laufzeitmodell ermöglichte es, dass ein Benutzer eine Anfrage ablehnt, ohne den Kontext zu verstehen, und genau dafür wird die Begründung benötigt.
Die Logik der Methode funktioniert wie folgt. Beim ersten Aufruf von requestPermissions für eine bestimmte Berechtigung gibt shouldShowRequestPermissionRationale false zurück — der Benutzer ist noch nicht auf den Dialog gestoßen. Wenn der Benutzer die Anfrage ablehnt (Deny drückt), beginnt die Methode, true zurückzugeben. Nach einer erneuten Ablehnung mit dem Never Ask Again-Flag gibt die Methode false zurück.
Vollständige Zustandstabelle:
| Zustand | shouldShowRationale | checkSelfPermission | Entwickleraktion |
|---|---|---|---|
| Nicht angefordert | false | DENIED | Systemdialog anzeigen |
| Gewährt | false | GRANTED | Funktion ausführen |
| Erstmals abgelehnt | true | DENIED | Begründung anzeigen, dann Systemdialog |
| Never Ask Again | false | DENIED | Zu Einstellungen weiterleiten |
Die Kombination shouldShowRequestPermissionRationale = false und checkSelfPermission = DENIED ist der am schwierigsten zu behandelnde Fall. Sie bedeutet entweder, dass die Berechtigung nie angefordert wurde oder dass Never Ask Again gesetzt ist. Der Entwickler muss diese beiden Zustände unterscheiden. Der einzige Weg ist, ein isFirstRequest-Flag in SharedPreferences oder mit SavedStateHandle zu speichern. Setzen Sie das Flag bei der ersten Anfrage, und wenn shouldShowRationale false zurückgibt, während das Flag bereits true ist — bedeutet dies Never Ask Again.
shouldShowRequestPermissionRationale wird zurückgesetzt, wenn der Benutzer die App deinstalliert und neu installiert, App-Daten löscht oder Berechtigungseinstellungen zurücksetzt. Nach einer Neuinstallation gibt die Methode für die erste Anfrage wieder false zurück. Systemaktualisierungen und Android-Versionsänderungen setzen den Verlauf nicht zurück — er wird in den App-Daten gespeichert.
Eine ordnungsgemäße Implementierung der Begründung umfasst drei Komponenten: Überprüfung von shouldShowRequestPermissionRationale nach der Ablehnung, Anzeige eines benutzerdefinierten Dialogs mit einer Erklärung und erneuter Aufruf von requestPermissions nach einer positiven Benutzerantwort. Der Dialog sollte kurz, spezifisch sein und erklären, warum die App diese bestimmte Berechtigung benötigt.
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("Warum Standortzugriff erforderlich ist")
.setMessage(
"Die App verwendet den Standort, um Orte auf der Karte" +
" zu markieren. Ohne diese Berechtigung" +
" funktioniert die Funktion nicht."
)
.setPositiveButton("Erlauben") { _, _ ->
requestPermissionLauncher.launch(permission)
}
.setNegativeButton("Abbrechen", null)
.show()
}
Die Best Practices von Material Design empfehlen die Verwendung eines Bottom Sheets oder Inline-Banners anstelle eines modalen Dialogs für Begründungen. Ein Bottom Sheet ist weniger aufdringlich und gibt dem Benutzer Kontext. Ein Inline-Element auf dem Bildschirm (z. B. eine Karte mit einer Erklärung und einem Erlauben-Button) zeigt, dass die Funktion ohne die Berechtigung nicht verfügbar ist, blockiert aber nicht die restliche Benutzeroberfläche.
Der Begründungstext sollte lokalisiert und an die spezifische Funktion angepasst werden. Verwenden Sie keine allgemeinen Phrasen wie „Dies wird für den Betrieb der App benötigt.“ Geben Sie konkret an: „Um das Wetter in Ihrer Nähe anzuzeigen“ oder „Um Fotos in der Galerie zu speichern.“ Spezifische Erklärungen erhöhen die Wahrscheinlichkeit der Berechtigungserteilung laut Google UX Research um 50 Prozent.
Der Unterschied zwischen shouldShowRequestPermissionRationale = true (erste Ablehnung) und false mit DENIED (Never Ask Again) ist ein zentraler Punkt bei der Berechtigungsbehandlung. Im ersten Fall zögerte der Benutzer, und eine zusätzliche Erklärung kann ihn überzeugen, den Zugriff zu gewähren. Im zweiten Fall hat der Benutzer eine endgültige Entscheidung getroffen, und die Wiederholung des Systemdialogs führt nur zu Verärgerung.
Der Behandlungsalgorithmus nach der Ablehnung sollte wie folgt aussehen:
Es ist wichtig, die Reihenfolge nicht zu verwechseln: zuerst shouldShowRequestPermissionRationale prüfen, nicht checkSelfPermission. checkSelfPermission gibt in beiden Fällen DENIED zurück. Nur shouldShowRequestPermissionRationale unterscheidet die erste Ablehnung von Never Ask Again. Verwenden Sie SavedStateHandle oder SharedPreferences, um das Flag „erste Anfrage wurde gestellt“ zu speichern — dies ist die einzige zuverlässige Methode, um „nie angefordert“ von „gesperrt“ zu unterscheiden.
Zeigen Sie die Begründung nur einmal an. Wenn der Benutzer die Anfrage nach dem Anzeigen der Begründung erneut ablehnt, zeigen Sie die Erklärung nicht noch einmal. Gehen Sie direkt zum Angebot, die Einstellungen zu öffnen. Das wiederholte Anzeigen von Begründungen wird als aufdringlich empfunden und senkt die App-Bewertung. Das optimale Szenario: Anfrage — Ablehnung — Begründung — erneute Anfrage — Ablehnung — Einstellungen.
Zeigen Sie die Begründung nicht vor der ersten Anfrage an. Einige Entwickler zeigen fälschlicherweise vor dem allerersten Dialog eine Erklärung an, mit der Begründung, dass „der Benutzer es verstehen muss.“ Dies verschlechtert die UX: Der Benutzer sieht zwei Dialoge hintereinander statt einem. Google empfiehlt, den Systemdialog sofort anzuzeigen und die Begründung erst nach einer Ablehnung.
Verwenden Sie eine kontextbezogene Begründung, die an den Moment gebunden ist, in dem die Funktion tatsächlich benötigt wird. Fordern Sie nicht alle Berechtigungen beim App-Start an — dies hat die niedrigste Zustimmungsrate. Fordern Sie KAMERA an, wenn der Benutzer auf „Foto aufnehmen“ tippt, und STANDORT, wenn er die Karte öffnet. Kontextbezogene Anfragen in Kombination mit einer Begründung erhöhen die Zustimmungsrate auf 80 Prozent gegenüber 30 Prozent bei der Anfrage beim Start.
Das Testen von shouldShowRequestPermissionRationale erfordert die Überprüfung der vier Tabellenzustände: nicht angefordert, gewährt, abgelehnt, Never Ask Again. In Komponententests verwenden Sie FakePermissionHandler mit konfigurierbarem shouldShowRationale-Verhalten. In Instrumentierungstests verwenden Sie UiAutomator oder Espresso mit Dialogantwortemulation.
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
)
}
}
Das wichtigste Szenario für einen Instrumentierungstest ist die Überprüfung, ob der Begründungsdialog nach der ersten Ablehnung tatsächlich angezeigt wird. Verwenden Sie Espresso mit Idling Resources, um auf den Systemdialog zu warten, drücken Sie dann Deny, überprüfen Sie das Erscheinen des benutzerdefinierten Erklärungsdialogs und drücken Sie Allow — überprüfen Sie die Gewährung. UIAutomator ermöglicht die Interaktion mit dem Systemdialog über den Button-Text, was den Test stabiler macht.
Testen Sie auch das Ablehnungsszenario innerhalb des Begründungsdialogs. Wenn der Benutzer im benutzerdefinierten Dialog auf Deny drückt, sollte shouldShowRequestPermissionRationale wieder true zurückgeben, da Never Ask Again noch nicht aktiviert ist. Die beste Praxis ist, nach zwei aufeinanderfolgenden Ablehnungen direkt zu den Einstellungen weiterzuleiten, um den Benutzer nicht mit wiederholten Erklärungen zu belästigen und die App-Bewertung nicht zu senken.
Häufig gestellte Fragen
true — wenn die Anfrage zuvor abgelehnt wurde und Never Ask Again nicht gesetzt ist. false — wenn die Berechtigung nie angefordert, gewährt oder dauerhaft gesperrt wurde. Die Kombination false + DENIED erfordert eine Überprüfung durch ein zusätzliches Flag.
Zeigen Sie die Begründung nur nach der ersten Ablehnung des Benutzers an, wenn shouldShowRequestPermissionRationale true zurückgegeben hat. Vor der ersten Anfrage ist keine Begründung erforderlich — dies verschlechtert die UX und erzeugt unnötige Dialoge.
Speichern Sie ein isFirstRequest-Flag in SharedPreferences oder SavedStateHandle. Wenn shouldShowRationale = false, checkSelfPermission = DENIED und das Flag true ist — ist Never Ask Again aktiv. Wenn das Flag false ist — handelt es sich um die erste Anfrage.
Zeigen Sie einen Dialog mit einem „Einstellungen öffnen“-Button, der den Benutzer zu ACTION_APPLICATION_DETAILS_SETTINGS weiterleitet. Rufen Sie requestPermissions nicht erneut auf — der Dialog wird nicht angezeigt und das Ergebnis kommt als DENIED ohne Meldung zurück.
Verwenden Sie in Komponententests FakePermissionHandler mit einem konfigurierbaren shouldShowRationale-Feld. Verwenden Sie in Instrumentierungstests Espresso oder UIAutomator mit Systemdialog-Emulation. Überprüfen Sie alle 4 Zustände aus der Tabelle.
Zusammenfassung
Wir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch