Services Google Play et autorisations d'exécution

Depuis Android 6.0 Marshmallow, Android utilise un modèle d'autorisation qui simplifie le processus d'installation le processus de mise à jour automatique. Les autorisations sont demandées au moment de l'exécution plutôt qu'avant l'installation d'applications. De plus, les utilisateurs peuvent choisir de refuser des autorisations spécifiques. Pour offrir cette flexibilité aux utilisateurs, vous devez vous assurer que votre application se comporte attendu lorsqu'un utilisateur active ou désactive une autorisation spécifique.

Les services Google Play eux-mêmes disposent d'autorisations d'exécution que les utilisateurs peuvent choisir refuser séparément des autorisations spécifiquement demandées par votre application. Les services Google Play obtiennent automatiquement toutes les autorisations nécessaires pour assurer la compatibilité avec ses API. Cependant, votre application doit toujours vérifier et demander l'exécution les autorisations nécessaires et de gérer de manière appropriée les erreurs lorsqu'un utilisateur a refusé aux services Google Play l'autorisation requise pour une API utilisée par votre application.

Il est recommandé de gérer les attentes de l'utilisateur en définissant des autorisations qui que peut nécessiter l'environnement d'exécution. Les bonnes pratiques suivantes vous aideront à éviter les problèmes potentiels.

Prérequis

Vous devez déclarer les autorisations dans le fichier AndroidManifest.xml. Exemple :

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

Consignes

Vérifier les autorisations avant d'appeler des API

Une fois que vous avez déclaré les API à utiliser dans votre AndroidManifest.xml, assurez-vous de disposer des autorisations requises avant d'appeler une API. Pour ce faire, utilisez 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 doit utiliser requestPermissions pour les demander. La réponse à cela est renvoyées dans un rappel que vous verrez à l'étape suivante.

Exemple :

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
    != PackageManager.PERMISSION_GRANTED) {
  // Check Permissions Now
  ActivityCompat.requestPermissions(this,
      new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
      REQUEST_LOCATION);
} else {
  // permission has been granted, continue as usual
  Task<Location> locationResult = LocationServices
      .getFusedLocationProviderClient(this /** Context */)
      .getLastLocation();
}

Implémenter le rappel d'autorisation de requête

Si l'autorisation dont votre application a besoin n'a pas été accordée par l'utilisateur, le La méthode requestPermissions doit être appelée pour demander au à l'utilisateur de les accorder. La réponse de l'utilisateur est capturée dans la Rappel onRequestPermissionsResult. Votre application doit et vérifiez toujours les valeurs renvoyées, car la requête peut être refusées ou annulée. Vous pouvez également demander et vérifier plusieurs autorisations à l'adresse L'exemple suivant ne vérifie qu'une seule autorisation.

public void onRequestPermissionsResult(int requestCode,
                                       String[] permissions,
                                       int[] grantResults) {
    if (requestCode == REQUEST_LOCATION) {
        if(grantResults.length == 1
           && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // We can now safely use the API we requested access to
            Task<Location> locationResult = LocationServices
                .getFusedLocationProviderClient(this /** Context */)
                .getLastLocation();
        } 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 pour les fonctionnalités de base application et que l'utilisateur a précédemment refusé la demande d'autorisation, votre application doit afficher une explication supplémentaire avant de redemander l'autorisation. Utilisateurs sont plus susceptibles d'accorder des autorisations lorsqu'ils comprennent pourquoi elles est nécessaire et les avantages immédiats pour eux.

Dans ce cas, avant l'appel requestPermissions, vous devez appeler shouldShowRequestPermissionRationale Si la valeur "true", vous devez créer une interface utilisateur pour afficher plus de contexte pour l'autorisation.

Par exemple, votre code peut se présenter comme suit:

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
    != PackageManager.PERMISSION_GRANTED) {
    // Check Permissions Now
    private static final int REQUEST_LOCATION = 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},
            ACCESS_FINE_LOCATION);
    }
} else {
    // permission has been granted, continue as usual
    Task<Location> locationResult = LocationServices
        .getFusedLocationProviderClient(this /** Context */)
        .getLastLocation();
}

Gérer les échecs de connexion

Si votre application utilise la version obsolète GoogleApiClient, lorsque vous appelez connect(), les services Google Play vérifient qu'il dispose de toutes les les autorisations nécessaires. Échec de connect() lorsqu'un groupe d'autorisations nécessaires par les services Google Play eux-mêmes sont manquants.

Si l'appel à connect() échoue, assurez-vous que votre application gère le échec de connexion. Si les services Google Play ne dispose pas des autorisations nécessaires, vous pouvez appeler startResolutionForResult() pour lancer le flux utilisateur pour les corriger.

Exemple :

@Override
public void onConnectionFailed(ConnectionResult result) {
    if (mResolvingError) {
        // Already attempting to resolve an error.
        return;
    } else if (result.hasResolution()) {
        try {
            mResolvingError = true;
            result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR);
        } catch (SendIntentException e) {
            // There was an error with the resolution intent. Try again.
            mGoogleApiClient.connect();
        }
    } else {
        // Show dialog using GooglePlayServicesUtil.getErrorDialog()
        showErrorDialog(result.getErrorCode());
        mResolvingError = true;
    }
}

Les appels d'API plus récents basés sur GoogleApi affichent automatiquement une boîte de dialogue (si le client est instancié avec une Activity) ou une notification dans la barre d'état système (si le client est instancié avec un Context) sur lequel l'utilisateur peut appuyer pour démarrer l'intent de résolution des autorisations. Les appels sont mis en file d'attente et une nouvelle tentative est effectuée une fois que le l'autorisation est accordée.