shouldShowRequestPermissionRationale est une méthode de l'API Android qui indique au développeur s'il doit afficher une explication à l'utilisateur avant de demander une autorisation dangereuse. Selon la Référence du Développeur Android, 2024, la méthode renvoie true si l'utilisateur a précédemment refusé la demande mais n'a pas activé le flag Never Ask Again. C'est un outil clé pour construire une UX respectueuse lors du travail avec les autorisations d'exécution.
Points Clés
shouldShowRequestPermissionRationale est une méthode des classes Activity et Fragment dans Android, disponible via ActivityCompat pour la compatibilité. Elle prend un nom d'autorisation et renvoie un Boolean indiquant s'il faut afficher à l'utilisateur une explication supplémentaire avant de demander à nouveau. La méthode est apparue dans Android 6.0 Marshmallow avec le modèle d'autorisations d'exécution.
Le mécanisme de justification est basé sur le suivi de l'historique d'interaction de l'utilisateur avec les boîtes de dialogue d'autorisations. Le système se souvient si l'utilisateur a refusé la demande précédemment. Si le refus a eu lieu sans activer le flag Never Ask Again, shouldShowRequestPermissionRationale renvoie true. C'est un signal pour le développeur : l'utilisateur ne comprend pas pourquoi l'autorisation est nécessaire, et une explication supplémentaire est requise. Selon les Directives de Conception Material de Google, afficher une boîte de dialogue de justification après le premier refus augmente la probabilité d'accorder à nouveau l'autorisation de 35 pour cent.
Il est important de comprendre la sémantique des valeurs de retour : true signifie qu'il est pertinent d'afficher la boîte de dialogue, false signifie que la boîte de dialogue n'est pas nécessaire (l'autorisation est déjà accordée ou n'a jamais été demandée) ou est inutile (Never Ask Again actif). La méthode ne garantit pas que la boîte de dialogue sera affichée — elle donne seulement une recommandation. Le développeur décide quelle interface utilisateur afficher en réponse.
shouldShowRequestPermissionRationale a été introduite au niveau d'API 23 avec un groupe de méthodes pour les autorisations d'exécution. Avant Android 6.0, toutes les autorisations étaient demandées lors de l'installation et aucun mécanisme d'explication n'était nécessaire — l'utilisateur acceptait ou rejetait la liste entière d'un coup. Le modèle d'exécution a permis à un utilisateur de refuser une demande sans comprendre le contexte, et c'est exactement pourquoi la justification est nécessaire.
La logique de la méthode fonctionne comme suit. Lors du premier appel à requestPermissions pour une autorisation spécifique, shouldShowRequestPermissionRationale renvoie false — l'utilisateur n'a pas encore rencontré la boîte de dialogue. Si l'utilisateur refuse la demande (appuie sur Refuser), la méthode commence à renvoyer true. Après un refus répété avec le flag Never Ask Again, la méthode renvoie false.
Tableau complet des états :
| État | shouldShowRationale | checkSelfPermission | Action du développeur |
|---|---|---|---|
| Non demandé | false | DENIED | Afficher la boîte de dialogue système |
| Accordé | false | GRANTED | Exécuter la fonction |
| Refusé première fois | true | DENIED | Afficher la justification, puis la boîte de dialogue système |
| Never Ask Again | false | DENIED | Rediriger vers Paramètres |
La combinaison shouldShowRequestPermissionRationale = false et checkSelfPermission = DENIED est le cas le plus difficile à traiter. Elle signifie que l'autorisation n'a jamais été demandée ou que Never Ask Again est activé. Le développeur doit distinguer ces deux états. La seule façon est de stocker un flag isFirstRequest dans SharedPreferences ou en utilisant SavedStateHandle. Définissez le flag lors de la première demande, et si shouldShowRationale renvoie false alors que le flag est déjà true — cela signifie Never Ask Again.
shouldShowRequestPermissionRationale est réinitialisé si l'utilisateur désinstalle et réinstalle l'application, efface les données de l'application ou réinitialise les paramètres d'autorisations. Après la réinstallation, la méthode renverra à nouveau false pour la première demande. Les mises à jour système et les changements de version Android ne réinitialisent pas l'historique — il est stocké dans les données de l'application.
Une implémentation appropriée de la justification comprend trois composants : vérifier shouldShowRequestPermissionRationale après le refus, afficher une boîte de dialogue personnalisée avec une explication, et rappeler requestPermissions après une réponse positive de l'utilisateur. La boîte de dialogue doit être brève, spécifique et expliquer pourquoi l'application a besoin de cette autorisation particulière.
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("Pourquoi l'accès à la localisation est nécessaire")
.setMessage(
"L'application utilise la localisation pour marquer" +
" des endroits sur la carte. Sans cette autorisation," +
" la fonction ne fonctionnera pas."
)
.setPositiveButton("Autoriser") { _, _ ->
requestPermissionLauncher.launch(permission)
}
.setNegativeButton("Annuler", null)
.show()
}
Les bonnes pratiques de Material Design recommandent d'utiliser une feuille inférieure ou une bannière en ligne plutôt qu'une boîte de dialogue modale pour la justification. Une feuille inférieure est moins intrusive et donne du contexte à l'utilisateur. Un élément en ligne à l'écran (par exemple, une carte avec une explication et un bouton Autoriser) montre que la fonction n'est pas disponible sans l'autorisation, mais ne bloque pas le reste de l'interface.
Le texte de justification doit être localisé et adapté à la fonction spécifique. N'utilisez pas de phrases génériques comme « Ceci est nécessaire au fonctionnement de l'application. » Spécifiez concrètement : « Pour afficher la météo près de chez vous » ou « Pour enregistrer des photos dans la galerie. » Les explications spécifiques augmentent la probabilité d'accorder l'autorisation de 50 pour cent selon la Recherche UX de Google.
La différence entre shouldShowRequestPermissionRationale = true (premier refus) et false avec DENIED (Never Ask Again) est un point clé dans la gestion des autorisations. Dans le premier cas, l'utilisateur hésitait, et une explication supplémentaire peut le convaincre d'accorder l'accès. Dans le second, l'utilisateur a pris une décision finale, et répéter la boîte de dialogue système ne fera que provoquer de l'irritation.
L'algorithme de traitement après un refus doit être le suivant :
Il est important de ne pas confondre l'ordre : vérifier d'abord shouldShowRequestPermissionRationale, pas checkSelfPermission. checkSelfPermission renverra toujours DENIED dans les deux cas. Seul shouldShowRequestPermissionRationale distingue le premier refus de Never Ask Again. Utilisez SavedStateHandle ou SharedPreferences pour stocker le flag « première demande effectuée » — c'est le seul moyen fiable de distinguer « jamais demandé » de « bloqué. »
Affichez la justification une seule fois. Si l'utilisateur refuse à nouveau la demande après avoir vu la justification, n'affichez plus l'explication. Passez directement à la proposition d'ouvrir les paramètres. Afficher la justification à plusieurs reprises est perçu comme une nuisance et réduit la note de l'application. Le scénario optimal : demande — refus — justification — nouvelle demande — refus — Paramètres.
N'affichez pas la justification avant la première demande. Certains développeurs affichent par erreur une explication avant la toute première boîte de dialogue, arguant que « l'utilisateur doit comprendre. » Cela nuit à l'UX : l'utilisateur voit deux boîtes de dialogue à la suite au lieu d'une. Google recommande d'afficher la boîte de dialogue système immédiatement, et la justification seulement après un refus.
Utilisez une justification contextuelle liée au moment où la fonction est réellement nécessaire. Ne demandez pas toutes les autorisations au démarrage de l'application — c'est le taux d'accord le plus bas. Demandez l'APPAREIL PHOTO lorsque l'utilisateur appuie sur « Prendre une photo » et la LOCALISATION lorsqu'il ouvre la carte. La demande contextuelle combinée à une justification augmente les accords à 80 pour cent contre 30 pour cent lors d'une demande au démarrage.
Tester shouldShowRequestPermissionRationale nécessite de vérifier les quatre états du tableau : non demandé, accordé, refusé, Never Ask Again. Dans les tests unitaires, utilisez FakePermissionHandler avec un comportement shouldShowRationale configurable. Dans les tests d'instrumentation, utilisez UiAutomator ou Espresso avec émulation de réponses de boîtes de dialogue.
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
)
}
}
Le scénario clé pour un test d'instrumentation est de vérifier que la boîte de dialogue de justification apparaît réellement après le premier refus. Utilisez Espresso avec des ressources d'attente pour attendre la boîte de dialogue système, puis appuyez sur Refuser, vérifiez l'apparition de la boîte de dialogue de justification personnalisée et appuyez sur Autoriser — vérifiez l'accord. UIAutomator permet d'interagir avec la boîte de dialogue système par le texte du bouton, ce qui rend le test plus stable.
Il faut également tester le scénario de refus à l'intérieur de la boîte de dialogue de justification. Si l'utilisateur appuie sur Refuser dans l'explication personnalisée, shouldShowRequestPermissionRationale doit renvoyer true à nouveau, car Never Ask Again n'est pas encore activé. La bonne pratique est de rediriger vers les paramètres après deux refus consécutifs pour éviter d'irriter l'utilisateur avec des explications répétées et de réduire la note de l'application.
Foire aux questions
true — si la demande a été refusée précédemment et que Never Ask Again n'est pas défini. false — si l'autorisation n'a jamais été demandée, accordée ou bloquée définitivement. La combinaison false + DENIED nécessite une vérification via un flag supplémentaire.
Affichez la justification seulement après le premier refus de l'utilisateur, lorsque shouldShowRequestPermissionRationale a renvoyé true. Avant la première demande, la justification n'est pas nécessaire — cela nuit à l'UX et crée des boîtes de dialogue inutiles.
Stockez un flag isFirstRequest dans SharedPreferences ou SavedStateHandle. Si shouldShowRationale = false, checkSelfPermission = DENIED et le flag est true — Never Ask Again est actif. Si le flag est false — c'est la première demande.
Affichez une boîte de dialogue avec un bouton « Ouvrir les paramètres » qui redirige l'utilisateur vers ACTION_APPLICATION_DETAILS_SETTINGS. N'appelez pas requestPermissions à nouveau — la boîte de dialogue n'apparaîtra pas et le résultat reviendra comme DENIED sans message.
Dans les tests unitaires, utilisez FakePermissionHandler avec un champ shouldShowRationale configurable. Dans les tests d'instrumentation, utilisez Espresso ou UIAutomator avec émulation de boîte de dialogue système. Vérifiez les 4 états du tableau.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi