Mit GoogleApiClient auf Google APIs zugreifen (eingestellt)

Mit dem Objekt GoogleApiClient („Google API-Client“) können Sie auf die in der Bibliothek der Google Play-Dienste bereitgestellten Google APIs zugreifen, z. B. Google Log-in, Spiele und Drive. Der Google API-Client ist ein gemeinsamer Einstiegspunkt für die Google Play-Dienste und verwaltet die Netzwerkverbindung zwischen dem Gerät des Nutzers und den einzelnen Google-Diensten.

Die neuere GoogleApi-Schnittstelle und ihre Implementierungen sind jedoch einfacher zu verwenden und die bevorzugte Methode für den Zugriff auf Play-Dienste-APIs. Siehe Auf Google APIs zugreifen.

In diesem Leitfaden erfahren Sie, wie Sie:

  • Verwalte deine Verbindung zu Google Play-Diensten automatisch.
  • Synchrone und asynchrone API-Aufrufe an beliebige Google Play-Dienste ausführen
  • In den seltenen Fällen, in denen das erforderlich ist, können Sie die Verbindung zu Google Play-Diensten manuell verwalten. Weitere Informationen finden Sie unter Manuell verwaltete Verbindungen.
Abbildung 1: Eine Abbildung, die zeigt, wie der Google API-Client eine Schnittstelle zur Verbindung mit den verfügbaren Google Play-Diensten wie Google Play Spiele und Google Drive bereitstellt

Installieren Sie zuerst die Bibliothek der Google Play-Dienste (Version 15 oder höher) für Ihr Android SDK. Falls noch nicht geschehen, folge der Anleitung unter Google Play Services SDK einrichten.

Automatisch verwaltete Verbindung herstellen

Nachdem das Projekt mit der Bibliothek der Google Play-Dienste verknüpft wurde, erstellen Sie eine Instanz von GoogleApiClient. Verwenden Sie dazu die GoogleApiClient.Builder APIs in der Methode onCreate() Ihrer Aktivität. Die Klasse GoogleApiClient.Builder bietet Methoden, mit denen Sie die gewünschten Google APIs und die gewünschten OAuth 2.0-Bereiche angeben können. Mit dem folgenden Codebeispiel wird eine GoogleApiClient-Instanz erstellt, die eine Verbindung zum Google Drive-Dienst herstellt:

GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this)
    .enableAutoManage(this /* FragmentActivity */,
                      this /* OnConnectionFailedListener */)
    .addApi(Drive.API)
    .addScope(Drive.SCOPE_FILE)
    .build();

Sie können demselben GoogleApiClient mehrere APIs und mehrere Bereiche hinzufügen. Dazu hängen Sie zusätzliche Aufrufe an addApi() und addScope() an.

Wichtig:Wenn du die Wearable API zusammen mit anderen APIs einem GoogleApiClient hinzufügst, können auf Geräten, auf denen die Wear OS App nicht installiert ist, Clientverbindungsfehler auftreten. Um Verbindungsfehler zu vermeiden, rufen Sie die Methode addApiIfAvailable() auf und übergeben Sie die Wearable API, damit Ihr Client die fehlende API problemlos verarbeiten kann. Weitere Informationen findest du unter Auf die Wearable API zugreifen.

Wenn Sie eine automatisch verwaltete Verbindung herstellen möchten, müssen Sie eine Implementierung für die Schnittstelle OnConnectionFailedListener angeben, damit nicht behebbare Verbindungsfehler empfangen werden können. Wenn die automatisch verwaltete GoogleApiClient-Instanz versucht, eine Verbindung zu Google APIs herzustellen, wird automatisch die UI angezeigt, um alle auflösbaren Verbindungsfehler zu beheben (z. B. wenn Google Play-Dienste aktualisiert werden müssen). Wenn ein Fehler auftritt, der nicht behoben werden kann, erhalten Sie einen Aufruf an onConnectionFailed().

Sie können auch eine optionale Implementierung für die ConnectionCallbacks-Schnittstelle angeben, wenn Ihre App wissen muss, wann die automatisch verwaltete Verbindung hergestellt oder unterbrochen wird. Wenn Ihre Anwendung beispielsweise Aufrufe zum Schreiben von Daten in Google APIs sendet, sollten diese erst aufgerufen werden, nachdem die Methode onConnected() aufgerufen wurde.

Hier ist eine Beispielaktivität, bei der die Callback-Schnittstellen implementiert und dem Google API-Client hinzugefügt werden:

import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import gms.drive.*;
import android.support.v4.app.FragmentActivity;

public class MyActivity extends FragmentActivity
        implements OnConnectionFailedListener {
    private GoogleApiClient mGoogleApiClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Create a GoogleApiClient instance
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .enableAutoManage(this /* FragmentActivity */,
                                  this /* OnConnectionFailedListener */)
                .addApi(Drive.API)
                .addScope(Drive.SCOPE_FILE)
                .build();

        // ...
    }

    @Override
    public void onConnectionFailed(ConnectionResult result) {
        // An unresolvable error has occurred and a connection to Google APIs
        // could not be established. Display an error message, or handle
        // the failure silently

        // ...
    }
}

Ihre GoogleApiClient-Instanz wird automatisch nach Ihren Aktivitätsaufrufen onStart() verbunden und nach dem Anruf von onStop() getrennt. Ihre Anwendung kann nach dem Erstellen von GoogleApiClient sofort Leseanfragen an Google APIs senden, ohne warten zu müssen, bis die Verbindung hergestellt ist.

Mit Google-Diensten kommunizieren

Nach der Verbindung kann der Client Lese- und Schreibaufrufe mit den dienstspezifischen APIs senden, für die Ihre Anwendung autorisiert ist. Dazu müssen die APIs und Bereiche angegeben werden, die Sie der GoogleApiClient-Instanz hinzugefügt haben.

Hinweis: Möglicherweise musst du deine App zuerst in der Google Developer Console registrieren, bevor du bestimmte Google-Dienste aufrufen kannst. Anleitungen dazu findest du im entsprechenden Startleitfaden für die verwendete API, z. B. zu Google Drive oder Google Log-in.

Wenn Sie mit GoogleApiClient eine Lese- oder Schreibanfrage ausführen, gibt der API-Client ein PendingResult-Objekt zurück, das die Anfrage darstellt. Dies geschieht unmittelbar, bevor die Anfrage an den Google-Dienst gesendet wird, den Ihre App aufruft.

Hier sehen Sie beispielsweise eine Anfrage zum Lesen einer Datei aus Google Drive, die ein PendingResult-Objekt enthält:

Query query = new Query.Builder()
        .addFilter(Filters.eq(SearchableField.TITLE, filename));
PendingResult<DriveApi.MetadataBufferResult> result = Drive.DriveApi.query(mGoogleApiClient, query);

Nachdem die Anwendung ein PendingResult-Objekt enthält, kann sie angeben, ob die Anfrage als asynchroner oder synchroner Aufruf verarbeitet werden soll.

Tipp:Ihre App kann Leseanfragen in die Warteschlange stellen, wenn sie nicht mit den Google Play-Diensten verbunden ist. Ihre Anwendung kann beispielsweise Methoden aufrufen, um eine Datei aus Google Drive zu lesen, unabhängig davon, ob Ihre GoogleApiClient-Instanz noch verbunden ist. Nachdem eine Verbindung hergestellt wurde, werden Leseanfragen in der Warteschlange ausgeführt. Schreibanfragen erzeugen einen Fehler, wenn deine App Schreibmethoden der Google Play-Dienste aufruft, während dein Google API-Client nicht verbunden ist.

Asynchrone Aufrufe verwenden

Um die Anfrage asynchron zu machen, rufen Sie setResultCallback() im PendingResult auf und geben Sie eine Implementierung der ResultCallback-Schnittstelle an. Hier sehen Sie beispielsweise die asynchron ausgeführte Anfrage:

private void loadFile(String filename) {
    // Create a query for a specific filename in Drive.
    Query query = new Query.Builder()
            .addFilter(Filters.eq(SearchableField.TITLE, filename))
            .build();
    // Invoke the query asynchronously with a callback method
    Drive.DriveApi.query(mGoogleApiClient, query)
            .setResultCallback(new ResultCallback<DriveApi.MetadataBufferResult>() {
        @Override
        public void onResult(DriveApi.MetadataBufferResult result) {
            // Success! Handle the query result.
            // ...
        }
    });
}

Wenn Ihre App ein Result-Objekt im onResult()-Callback empfängt, wird es als Instanz der entsprechenden abgeleiteten Klasse bereitgestellt, wie von der verwendeten API angegeben, z. B. DriveApi.MetadataBufferResult.

Synchrone Aufrufe verwenden

Wenn der Code in einer streng definierten Reihenfolge ausgeführt werden soll, z. B. weil das Ergebnis eines Aufrufs als Argument für einen anderen erforderlich ist, können Sie die Anfrage synchron machen. Rufen Sie dazu await() für den PendingResult auf. Dadurch wird der Thread blockiert und das Objekt Result wird zurückgegeben, wenn die Anfrage abgeschlossen ist. Dieses Objekt wird als Instanz der entsprechenden abgeleiteten Klasse bereitgestellt, wie von der von Ihnen verwendeten API angegeben, z. B. DriveApi.MetadataBufferResult.

Da der Thread durch das Aufrufen von await() blockiert wird, bis das Ergebnis eintrifft, sollte Ihre Anwendung niemals synchrone Anfragen an Google APIs im UI-Thread senden. Ihre Anwendung kann mithilfe eines AsyncTask-Objekts einen neuen Thread erstellen und diesen Thread für die synchrone Anfrage verwenden.

Das folgende Beispiel zeigt, wie Sie einen synchronen Aufruf an Google Drive senden:

private void loadFile(String filename) {
    new GetFileTask().execute(filename);
}

private class GetFileTask extends AsyncTask {
    protected void doInBackground(String filename) {
        Query query = new Query.Builder()
                .addFilter(Filters.eq(SearchableField.TITLE, filename))
                .build();
        // Invoke the query synchronously
        DriveApi.MetadataBufferResult result =
                Drive.DriveApi.query(mGoogleApiClient, query).await();

        // Continue doing other stuff synchronously
        // ...
    }
}

Auf die Wearable API zugreifen

Die Wearable API bietet einen Kommunikationskanal für Apps, die auf Handheld- und Wearable-Geräten ausgeführt werden. Die API besteht aus einer Reihe von Datenobjekten, die das System senden und synchronisieren kann, sowie aus Listenern, die Ihre Anwendungen mithilfe einer Datenschicht über wichtige Ereignisse informieren. Die Wearable API ist auf Geräten mit Android 4.3 (API-Level 18) oder höher verfügbar, wenn ein Wearable-Gerät verbunden und die Wear OS-Companion-App auf dem Gerät installiert ist.

Eigenständige Wearable API verwenden

Wenn deine App die Wearable API, aber keine anderen Google APIs verwendet, kannst du diese API über die Methode addApi() hinzufügen. Das folgende Beispiel zeigt, wie Sie die Wearable API Ihrer GoogleApiClient-Instanz hinzufügen:

GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this)
    .enableAutoManage(this /* FragmentActivity */,
                      this /* OnConnectionFailedListener */)
    .addApi(Wearable.API)
    .build();

Wenn die Wearable API nicht verfügbar ist, schlagen Verbindungsanfragen, die die Wearable API enthalten, mit dem Fehlercode API_UNAVAILABLE fehl.

Das folgende Beispiel zeigt, wie Sie feststellen können, ob die Wearable API verfügbar ist:

// Connection failed listener method for a client that only
// requests access to the Wearable API
@Override
public void onConnectionFailed(ConnectionResult result) {
    if (result.getErrorCode() == ConnectionResult.API_UNAVAILABLE) {
        // The Wearable API is unavailable
    }
    // ...
}

Wearable API mit anderen Google APIs verwenden

Wenn deine App die Wearable API zusätzlich zu anderen Google APIs verwendet, rufe die Methode addApiIfAvailable() auf und übergib die Wearable API, um zu prüfen, ob sie verfügbar ist. Mit dieser Prüfung kannst du dafür sorgen, dass deine App in Fällen, in denen die API nicht verfügbar ist, korrekt reagieren kann.

Das folgende Beispiel zeigt, wie Sie auf die Wearable API zusammen mit der Drive API zugreifen:

// Create a GoogleApiClient instance
mGoogleApiClient = new GoogleApiClient.Builder(this)
        .enableAutoManage(this /* FragmentActivity */,
                          this /* OnConnectionFailedListener */)
        .addApi(Drive.API)
        .addApiIfAvailable(Wearable.API)
        .addScope(Drive.SCOPE_FILE)
        .build();

Im Beispiel oben kann der GoogleApiClient eine Verbindung zu Google Drive herstellen, ohne eine Verbindung zur Wearable API herzustellen, wenn diese nicht verfügbar ist. Nachdem Sie die GoogleApiClient-Instanz verbunden haben, prüfen Sie, ob die Wearable API verfügbar ist, bevor Sie die API-Aufrufe ausführen:

boolean wearAvailable = mGoogleApiClient.hasConnectedApi(Wearable.API);

API-Verbindungsfehler ignorieren

Wenn Sie addApi() aufrufen und GoogleApiClient keine Verbindung zu dieser API herstellen kann, schlägt der gesamte Verbindungsvorgang für diesen Client fehl und löst den onConnectionFailed()-Callback aus.

Mit addApiIfAvailable() können Sie einen API-Verbindungsfehler registrieren, der ignoriert werden soll. Wenn eine API, die mit addApiIfAvailable() hinzugefügt wurde, aufgrund eines nicht behebbaren Fehlers (z. B. API_UNAVAILABLE für Wear) keine Verbindung herstellen kann, wird diese API aus der GoogleApiClient entfernt und der Client stellt eine Verbindung zu anderen APIs her. Wenn eine API-Verbindung jedoch aufgrund eines behebbaren Fehlers fehlschlägt (z. B. bei einem OAuth-Intent zur Auflösung der Einwilligung), schlägt der Clientverbindungsvorgang fehl. Wenn Sie eine automatisch verwaltete Verbindung verwenden, versucht der GoogleApiClient, solche Fehler nach Möglichkeit zu beheben. Bei Verwendung einer manuell verwalteten Verbindung wird ein ConnectionResult mit einem Auflösungs-Intent an den onConnectionFailed()-Callback gesendet. API-Verbindungsfehler werden nur ignoriert, wenn der Fehler nicht behoben werden kann und die API mit addApiIfAvailable() hinzugefügt wurde. Informationen zum Implementieren der manuellen Behandlung von Verbindungsfehlern finden Sie unter Verbindungsfehler beheben.

Da mit addApiIfAvailable() hinzugefügte APIs möglicherweise nicht immer in der verbundenen Instanz GoogleApiClient vorhanden sind, sollten Sie Aufrufe an diese APIs verhindern, indem Sie mit hasConnectedApi() eine Prüfung hinzufügen. Wenn Sie herausfinden möchten, warum eine bestimmte API keine Verbindung herstellen konnte, obwohl der gesamte Verbindungsvorgang für den Client erfolgreich war, rufen Sie getConnectionResult() auf und rufen Sie den Fehlercode vom Objekt ConnectionResult ab. Wenn Ihr Client eine API aufruft, obwohl sie nicht mit dem Client verbunden ist, schlägt der Aufruf mit dem Statuscode API_NOT_AVAILABLE fehl.

Wenn für die API, die Sie über addApiIfAvailable() hinzufügen, ein oder mehrere Bereiche erforderlich sind, fügen Sie diese Bereiche als Parameter in den addApiIfAvailable()-Methodenaufruf ein, anstatt die Methode addScope() zu verwenden. Mit diesem Ansatz hinzugefügte Bereiche werden möglicherweise nicht angefordert, wenn die API-Verbindung vor Erhalt der OAuth-Zustimmung fehlschlägt. Mit addScope() hinzugefügte Bereiche hingegen werden immer angefordert.

Manuell verwaltete Verbindungen

Im Großteil dieses Leitfadens wird beschrieben, wie Sie mit der Methode enableAutoManage eine automatisch verwaltete Verbindung mit automatisch behobenen Fehlern herstellen. In fast allen Fällen ist dies die beste und einfachste Möglichkeit, um über Ihre Android-App eine Verbindung zu Google APIs herzustellen. Es gibt jedoch einige Situationen, in denen Sie eine manuell verwaltete Verbindung zu Google APIs in Ihrer App verwenden möchten:

  • Um außerhalb einer Aktivität auf Google APIs zuzugreifen oder die Kontrolle über die API-Verbindung zu behalten
  • So passen Sie die Behandlung und Lösung von Verbindungsfehlern an:

Dieser Abschnitt enthält Beispiele für diese und andere erweiterte Anwendungsfälle.

Manuell verwaltete Verbindung starten

Wenn Sie eine manuell verwaltete Verbindung zu GoogleApiClient herstellen möchten, müssen Sie eine Implementierung für die Callback-Schnittstellen ConnectionCallbacks und OnConnectionFailedListener angeben. Diese Schnittstellen empfangen Callbacks als Antwort auf die asynchrone Methode connect(), wenn die Verbindung zu den Google Play-Diensten erfolgreich ist, fehlschlägt oder unterbrochen wird.

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addApi(Drive.API)
            .addScope(Drive.SCOPE_FILE)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build()

Wenn Sie eine Verbindung manuell verwalten, müssen Sie die Methoden connect() und disconnect() an den richtigen Stellen im Lebenszyklus Ihrer Anwendung aufrufen. In einem Aktivitätskontext empfiehlt es sich, connect() in der onStart()-Methode Ihrer Aktivität und disconnect() in der onStop()-Methode Ihrer Aktivität aufzurufen. Die Methoden connect() und disconnect() werden bei Verwendung einer automatisch verwalteten Verbindung automatisch aufgerufen.

Wenn Sie GoogleApiClient verwenden, um sich mit APIs zu verbinden, die eine Authentifizierung erfordern, wie Google Drive oder Google Play Spiele, ist es sehr wahrscheinlich, dass der erste Verbindungsversuch fehlschlägt. Ihre App erhält dann einen Aufruf an onConnectionFailed() mit dem Fehler SIGN_IN_REQUIRED, da das Nutzerkonto nicht angegeben wurde.

Verbindungsfehler beheben

Wenn deine App einen Aufruf des onConnectionFailed()-Callbacks empfängt, solltest du hasResolution() für das bereitgestellte ConnectionResult-Objekt aufrufen. Wird der Wert „true“ zurückgegeben, kann Ihre Anwendung den Nutzer auffordern, sofort Maßnahmen zur Behebung des Fehlers zu ergreifen. Dazu ruft er startResolutionForResult() für das ConnectionResult-Objekt auf. Die Methode startResolutionForResult() verhält sich in dieser Situation wie startActivityForResult() und startet eine dem Kontext entsprechende Aktivität, die dem Nutzer bei der Behebung des Fehlers hilft (z. B. eine Aktivität, die dem Nutzer bei der Auswahl eines Kontos hilft).

Wenn hasResolution() „false“ zurückgibt, sollte Ihre Anwendung GoogleApiAvailability.getErrorDialog() aufrufen und den Fehlercode an diese Methode übergeben. Dadurch wird ein von den Google Play-Diensten bereitgestelltes Dialog zurückgegeben, das zum Fehler passt. Das Dialogfeld kann einfach eine Meldung enthalten, in der der Fehler erläutert wird, oder eine Aktion zum Starten einer Aktivität, mit der der Fehler behoben werden kann, z. B. wenn der Nutzer eine neuere Version der Google Play-Dienste installieren muss.

Die Callback-Methode onConnectionFailed() sollte jetzt beispielsweise so aussehen:

public class MyActivity extends Activity
        implements ConnectionCallbacks, OnConnectionFailedListener {

    // Request code to use when launching the resolution activity
    private static final int REQUEST_RESOLVE_ERROR = 1001;
    // Unique tag for the error dialog fragment
    private static final String DIALOG_ERROR = "dialog_error";
    // Bool to track whether the app is already resolving an error
    private boolean mResolvingError = false;

    // ...

    @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 GoogleApiAvailability.getErrorDialog()
            showErrorDialog(result.getErrorCode());
            mResolvingError = true;
        }
    }

    // The rest of this code is all about building the error dialog

    /* Creates a dialog for an error message */
    private void showErrorDialog(int errorCode) {
        // Create a fragment for the error dialog
        ErrorDialogFragment dialogFragment = new ErrorDialogFragment();
        // Pass the error that should be displayed
        Bundle args = new Bundle();
        args.putInt(DIALOG_ERROR, errorCode);
        dialogFragment.setArguments(args);
        dialogFragment.show(getSupportFragmentManager(), "errordialog");
    }

    /* Called from ErrorDialogFragment when the dialog is dismissed. */
    public void onDialogDismissed() {
        mResolvingError = false;
    }

    /* A fragment to display an error dialog */
    public static class ErrorDialogFragment extends DialogFragment {
        public ErrorDialogFragment() { }

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            // Get the error code and retrieve the appropriate dialog
            int errorCode = this.getArguments().getInt(DIALOG_ERROR);
            return GoogleApiAvailability.getInstance().getErrorDialog(
                    this.getActivity(), errorCode, REQUEST_RESOLVE_ERROR);
        }

        @Override
        public void onDismiss(DialogInterface dialog) {
            ((MyActivity) getActivity()).onDialogDismissed();
        }
    }
}

Nachdem der Nutzer das von startResolutionForResult() bereitgestellte Dialogfeld abgeschlossen oder die Meldung von GoogleApiAvailability.getErrorDialog() geschlossen hat, erhält Ihre Aktivität den onActivityResult()-Callback mit dem Ergebniscode RESULT_OK. Ihre Anwendung kann dann connect() noch einmal aufrufen. Beispiel:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_RESOLVE_ERROR) {
        mResolvingError = false;
        if (resultCode == RESULT_OK) {
            // Make sure the app is not already connected or attempting to connect
            if (!mGoogleApiClient.isConnecting() &&
                    !mGoogleApiClient.isConnected()) {
                mGoogleApiClient.connect();
            }
        }
    }
}

Im Code oben ist Ihnen wahrscheinlich der boolesche Wert mResolvingError aufgefallen. So wird der Status der Anwendung erfasst, während der Nutzer den Fehler behebt, um wiederholte Versuche zu vermeiden, denselben Fehler zu beheben. Während das Dialogfeld zur Kontoauswahl angezeigt wird, um dem Nutzer bei der Behebung des Fehlers SIGN_IN_REQUIRED zu helfen, kann er den Bildschirm drehen. Dadurch wird die Aktivität neu erstellt und die Methode onStart() noch einmal aufgerufen. Anschließend wird connect() noch einmal aufgerufen. Dies führt zu einem weiteren Aufruf von startResolutionForResult(), wodurch ein weiteres Dialogfeld zur Kontoauswahl vor dem vorhandenen Dialogfeld erstellt wird.

Dieser boolesche Wert erfüllt nur dann seinen beabsichtigten Zweck, wenn er über Aktivitätsinstanzen hinweg bestehen bleibt. Im nächsten Abschnitt wird erläutert, wie du den Fehlerbehandlungsstatus deiner App trotz anderer Nutzeraktionen oder ‐ereignisse auf dem Gerät beibehalten kannst.

Status beim Beheben eines Fehlers beibehalten

Damit der Code nicht während eines früheren Versuchs zur Fehlerbehebung in onConnectionFailed() ausgeführt wird, müssen Sie einen booleschen Wert beibehalten, der erfasst, ob Ihre Anwendung bereits versucht, einen Fehler zu beheben.

Wie im Codebeispiel oben gezeigt, sollte in der Anwendung jedes Mal, wenn startResolutionForResult() aufgerufen oder das Dialogfeld von GoogleApiAvailability.getErrorDialog() angezeigt wird, ein boolescher Wert auf true festgelegt werden. Wenn deine App dann RESULT_OK im onActivityResult()-Callback empfängt, setze den booleschen Wert auf false.

Um den booleschen Wert bei Neustarts von Aktivitäten (z. B. wenn der Nutzer den Bildschirm dreht) zu verfolgen, speichern Sie ihn mit onSaveInstanceState() in den gespeicherten Instanzdaten der Aktivität:

private static final String STATE_RESOLVING_ERROR = "resolving_error";

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putBoolean(STATE_RESOLVING_ERROR, mResolvingError);
}

Stellen Sie dann den gespeicherten Zustand in onCreate() wieder her:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // ...
    mResolvingError = savedInstanceState != null
            && savedInstanceState.getBoolean(STATE_RESOLVING_ERROR, false);
}

Jetzt können Sie Ihre App sicher ausführen und manuell eine Verbindung zu den Google Play-Diensten herstellen.