Depuis Android 6.0 Marshmallow, Android utilise un modèle d'autorisations qui simplifie le processus d'installation et de mise à jour automatique des applications. Les autorisations sont demandées au moment de l'exécution, et non avant l'installation de l'application. Les utilisateurs peuvent également choisir de refuser des autorisations spécifiques. Pour offrir cette flexibilité aux utilisateurs, vous devez vous assurer que votre application se comporte comme prévu lorsqu'un utilisateur active ou désactive une autorisation spécifique.
Les services Google Play disposent eux-mêmes d'autorisations d'exécution que les utilisateurs peuvent choisir de refuser séparément de celles spécifiquement demandées par votre application. Les services Google Play obtiennent automatiquement toutes les autorisations dont ils ont besoin pour prendre en charge leurs API. Toutefois, votre application doit toujours vérifier et demander les autorisations d'exécution nécessaires, et gérer correctement les erreurs dans les cas où un utilisateur a refusé aux services Google Play une autorisation requise pour une API utilisée par votre application.
Il est recommandé de gérer les attentes de l'utilisateur lors de la définition des autorisations dont le runtime peut avoir besoin. Les bonnes pratiques suivantes vous aideront à éviter les problèmes potentiels.
Prérequis
Vous devrez déclarer les autorisations dans votre fichier AndroidManifest.xml
.
Exemple :
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Consignes
Vérifier les autorisations avant d'appeler les API
Une fois que vous avez déclaré les API que vous souhaitez utiliser dans votre fichier AndroidManifest.xml
, vérifiez que vous disposez de l'autorisation requise avant d'appeler une API. Pour ce faire, vous pouvez utiliser la méthode checkSelfPermission
de ActivityCompat
ou ContextCompat
.
Si l'appel renvoie la valeur "false", cela signifie que les autorisations ne sont pas accordées et que vous devez utiliser requestPermissions
pour les demander. La réponse à cette requête est renvoyée dans un rappel que vous verrez à l'étape suivante.
Exemple :
Kotlin
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Request Permissions Now ActivityCompat.requestPermissions( this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), REQUEST_LOCATION_PERMISSION_CODE) } else { // permission has been granted, continue as usual val locationResult = LocationServices .getFusedLocationProviderClient(this /* Context */) .lastLocation }
Java
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Request Permissions Now ActivityCompat.requestPermissions( this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_PERMISSION_CODE); } else { // permission has been granted, continue as usual TasklocationResult = LocationServices .getFusedLocationProviderClient(this /** Context */) .getLastLocation(); }
Implémenter le rappel de demande d'autorisation
Si l'autorisation dont votre application a besoin n'a pas été accordée par l'utilisateur, la méthode requestPermissions
doit être appelée pour demander à l'utilisateur de l'accorder. La réponse de l'utilisateur est capturée dans le rappel onRequestPermissionsResult
. Votre application doit implémenter cette méthode et toujours vérifier les valeurs de retour, car la requête peut être refusée ou annulée. Vous pouvez également demander et vérifier plusieurs autorisations à la fois. L'exemple suivant ne vérifie qu'une seule autorisation.
Kotlin
fun onRequestPermissionsResult( requestCode: Int, permissions: Array, grantResults: IntArray ) { if (requestCode == REQUEST_LOCATION_PERMISSION_CODE) { if (grantResults.singleOrNull() == PackageManager.PERMISSION_GRANTED) { // We can now safely use the API we requested access to val locationResult: Task = LocationServices .getFusedLocationProviderClient(this /* Context */) .lastLocation // Request the last known location. } else { // Permission was denied or request was cancelled } } }
Java
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if (requestCode == REQUEST_LOCATION_PERMISSION_CODE) { if(grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // We can now safely use the API we requested access to TasklocationResult = LocationServices .getFusedLocationProviderClient(this /** Context */) .getLastLocation(); // Request the last known location. } else { // Permission was denied or request was cancelled } } }
Afficher la justification de l'autorisation
Si les autorisations demandées par votre application sont nécessaires à ses fonctionnalités de base et que l'utilisateur a déjà refusé la demande d'autorisation, votre application doit afficher une explication supplémentaire avant de demander à nouveau l'autorisation. Les utilisateurs sont plus susceptibles d'accorder des autorisations lorsqu'ils comprennent pourquoi elles sont nécessaires et l'avantage immédiat qu'ils en tireront.
Dans ce cas, avant d'appeler requestPermissions
, vous devez appeler shouldShowRequestPermissionRationale
. Si la valeur renvoyée est "true", vous devez créer une interface utilisateur pour afficher le contexte supplémentaire de l'autorisation.
Par exemple, votre code peut se présenter comme suit :
Kotlin
private const val REQUEST_LOCATION_PERMISSION_CODE = 2 if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Check Permissions Now if ActivityCompat.shouldShowRequestPermissionRationale( this, Manifest.permission.ACCESS_FINE_LOCATION ) { // Display UI and wait for user interaction } else { ActivityCompat.requestPermissions( this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), REQUEST_LOCATION_PERMISSION_CODE) } } else { // Permission has already been granted, continue as usual val locationResult: Task= LocationServices .getFusedLocationProviderClient(this /* Context */) .lastLocation }
Java
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Check Permissions Now private static final int REQUEST_LOCATION_PERMISSION_CODE = 2; if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) { // Display UI and wait for user interaction } else { ActivityCompat.requestPermissions( this, new String[]{Manifest.permission.LOCATION_FINE}, REQUEST_LOCATION_PERMISSION_CODE); } } else { // permission has been granted, continue as usual TasklocationResult = LocationServices .getFusedLocationProviderClient(this /** Context */) .getLastLocation(); }
Les appels d'API des services Google Play affichent automatiquement une boîte de dialogue (si le client est instancié avec un Activity
) ou une notification dans la barre d'état système (si le client est instancié avec un Context
) sur laquelle l'utilisateur peut appuyer pour démarrer l'intent de résolution des autorisations. Les appels seront mis en file d'attente et réessayés une fois l'autorisation accordée.