Google Play-Dienste und Laufzeitberechtigungen

Seit Android 6.0 Marshmallow nutzt Android Berechtigungsmodell, das die App-Installation und automatisch aktualisiert werden. Berechtigungen werden zur Laufzeit und nicht vorher angefordert App-Installation. Außerdem haben Nutzer die Möglichkeit, bestimmte Berechtigungen abzulehnen. Um Nutzern diese Flexibilität zu bieten, müssen Sie sicherstellen, dass sich Ihre App wie wird erwartet, wenn ein Nutzer eine bestimmte Berechtigung aktiviert oder deaktiviert.

Die Google Play-Dienste selbst haben Laufzeitberechtigungen, die Nutzer auswählen können nicht getrennt von den von Ihrem Konto angeforderten Berechtigungen . Die Google Play-Dienste erhalten automatisch alle erforderlichen Berechtigungen zur Unterstützung der APIs. Ihre Anwendung sollte jedoch trotzdem die Laufzeit prüfen und anfordern. Berechtigungen erteilen und Fehler angemessen behandeln, wenn ein Nutzer hat den Google Play-Diensten eine Berechtigung verweigert, die für eine von Ihrer App verwendete API erforderlich ist.

Es empfiehlt sich, die Erwartungen der Nutzenden zu berücksichtigen, indem Sie Berechtigungen festlegen, die die Laufzeit möglicherweise erfordert. Mit den folgenden Best Practices können Sie mögliche Probleme.

Vorbereitung

Sie müssen Berechtigungen in Ihrer AndroidManifest.xml-Datei deklarieren. Beispiel:

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

Richtlinien

Berechtigungen vor dem API-Aufruf prüfen

Nachdem Sie die APIs deklariert haben, die Sie in Ihrem AndroidManifest.xml-Datei prüfen, ob Sie die erforderliche Berechtigung haben bevor eine API aufgerufen wird. Dazu können Sie die Methode checkSelfPermission verwenden. von ActivityCompat oder ContextCompat.

Wenn der Aufruf „false“ zurückgibt, wurden die Berechtigungen nicht gewährt und Sie sollten sie mit requestPermissions anfordern. Die Antwort lautet die in einem Callback zurückgegeben werden, den Sie im nächsten Schritt sehen.

Beispiel:

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();
}

Callback für die Anfrageberechtigung implementieren

Wenn die Berechtigung, die deine App benötigt, nicht vom Nutzer erteilt wurde, ist der requestPermissions sollte aufgerufen werden, um die zu gewähren. Die Antwort der Nutzenden wird im onRequestPermissionsResult-Callback Ihre App sollte implementieren und immer die Rückgabewerte überprüfen, da die Anfrage abgelehnt oder storniert wurden. Sie können auch unter folgendem Link mehrere Berechtigungen anfordern und prüfen: einmal – im folgenden Beispiel wird nur nach einer Berechtigung gesucht.

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
        }
    }
}

Berechtigungsbegründung zeigen

Sind die von deiner App angeforderten Berechtigungen für die Hauptfunktionen der und der Nutzer die Berechtigungsanfrage zuvor abgelehnt hat, sollte deine App eine zusätzliche Erklärung anzuzeigen, bevor Sie die Berechtigung noch einmal anfordern. Nutzer*innen gewähren eher Berechtigungen, wenn sie verstehen, warum die Berechtigung und der unmittelbare Nutzen für sie.

Rufen Sie in diesem Fall vor der aufrufenden requestPermissions-Datei den folgenden Befehl auf: shouldShowRequestPermissionRationale Wenn Folgendes zurückgegeben wird: true gesetzt ist, sollten Sie eine Benutzeroberfläche erstellen, die zusätzlichen Kontext für die Berechtigung.

Ihr Code könnte beispielsweise so aussehen:

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();
}

Verbindungsfehler beheben

Wenn Ihre App das verworfene GoogleApiClient verwendet, führen Sie beim Aufruf connect() überprüft, ob die Google Play-Dienste über alle die erforderlichen Berechtigungen erforderlich sind. connect() schlägt fehl, wenn Berechtigungsgruppen die von den Google Play-Diensten selbst benötigt werden.

Wenn der Aufruf von connect() fehlschlägt, achte darauf, dass deine App den Verbindungsfehler korrekt. Wenn die Google Play-Dienste selbst keine Berechtigungen hat, können Sie startResolutionForResult() aufrufen, um den User Flow zu initiieren, um sie zu beheben.

Beispiel:

@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;
    }
}

Bei neueren GoogleApi-basierten API-Aufrufen wird automatisch entweder ein Dialogfeld angezeigt (wenn der Client mit einer Activity) oder in der Taskleiste (falls wird der Client mit einer Context instanziiert), auf die der Nutzer tippen kann, um Intent für die Auflösung von Berechtigungen. Anrufe werden in die Warteschlange gestellt und wiederholt, sobald Berechtigung wurde gewährt.