Mit GoogleApiClient auf Google APIs zugreifen (eingestellt)

Sie können das Objekt GoogleApiClient („Google API-Client“) verwenden, um auf die Google APIs in der Google Play-Dienstebibliothek zuzugreifen (z. B. Google Sign-In, Spiele und Drive). Der Google API-Client bietet einen gemeinsamen Einstiegspunkt für Google Play-Dienste und verwaltet die Netzwerkverbindung zwischen dem Gerät des Nutzers und den einzelnen Google-Diensten.

Die neuere GoogleApi-Benutzeroberfläche und ihre Implementierungen sind jedoch einfacher zu verwenden und die bevorzugte Methode, um auf Play-Dienst-APIs zuzugreifen. Weitere Informationen finden Sie unter Auf Google APIs zugreifen.

In diesem Leitfaden erfahren Sie, wie Sie:

  • Verbindung zu Google Play-Diensten automatisch verwalten
  • Synchrone und asynchrone API-Aufrufe an alle Google Play-Dienste ausführen
  • Sie können die Verbindung zu den Google Play-Diensten in seltenen Fällen manuell verwalten. Weitere Informationen finden Sie unter Manuell verwaltete Verbindungen.
Abbildung 1: Eine Abbildung, die zeigt, wie der Google API-Client eine Benutzeroberfläche für die Verbindung und Aufrufe aller verfügbaren Google Play-Dienste wie Google Play Spiele und Google Drive bereitstellt.

Zuerst müssen Sie die Google Play-Dienste-Bibliothek (Version 15 oder höher) für Ihr Android SDK installieren. Folgen Sie der Anleitung unter Google Play Services SDK einrichten, falls Sie dies noch nicht getan haben.

Automatisch verwaltete Verbindung starten

Nachdem Ihr Projekt mit der Google Play-Dienstebibliothek verknüpft ist, erstellen Sie eine Instanz von GoogleApiClient mithilfe der 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 OAuth 2.0-Bereiche angeben können. Hier ein Codebeispiel, mit dem eine GoogleApiClient-Instanz erstellt wird, 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 derselben GoogleApiClient mehrere APIs und mehrere Bereiche hinzufügen, indem Sie addApi() und addScope() zusätzliche Aufrufe anhängen.

Wichtig:Wenn Sie die Wearable API zusammen mit anderen APIs einer GoogleApiClient hinzufügen, können auf Geräten, auf denen die Wear OS App nicht installiert ist, Clientverbindungsfehler auftreten. Um Verbindungsfehler zu vermeiden, rufe die Methode addApiIfAvailable() auf und gib die Wearable API an, damit dein Client die fehlende API ordnungsgemäß verarbeiten kann. Weitere Informationen finden Sie unter Auf die Wearable API zugreifen.

Wenn Sie eine automatisch verwaltete Verbindung starten möchten, müssen Sie eine Implementierung für die OnConnectionFailedListener-Schnittstelle angeben, um nicht behebbare Verbindungsfehler zu erhalten. Wenn Ihre automatisch verwaltete GoogleApiClient-Instanz versucht, eine Verbindung zu Google APIs herzustellen, wird automatisch eine Benutzeroberfläche angezeigt, über die sich behebbare Verbindungsfehler beheben lassen (z. B. wenn Google Play-Dienste aktualisiert werden müssen). Wenn ein Fehler auftritt, der nicht behoben werden kann, erhalten Sie einen Anruf unter onConnectionFailed().

Sie können auch eine optionale Implementierung für die ConnectionCallbacks-Oberfläche angeben, wenn Ihre App wissen muss, wann die automatisch verwaltete Verbindung hergestellt oder ausgesetzt wird. Wenn Ihre App beispielsweise Aufrufe zum Schreiben von Daten in Google APIs ausführt, sollten diese erst nach dem Aufruf der Methode onConnected() erfolgen.

Hier ist ein Beispiel für eine Aktivität, in 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 stellt automatisch eine Verbindung her, nachdem Ihre Aktivität onStart() aufgerufen hat, und trennt die Verbindung, nachdem onStop() aufgerufen wurde. Ihre App kann sofort nach dem Erstellen von GoogleApiClient Leseanfragen an Google APIs senden, ohne auf die Fertigstellung der Verbindung zu warten.

Kommunikation mit Google-Diensten

Nach der Verbindung kann Ihr Client Lese- und Schreibaufrufe mit den dienstspezifischen APIs ausführen, für die Ihre App autorisiert ist. Diese werden durch die APIs und Bereiche bestimmt, die Sie Ihrer GoogleApiClient-Instanz hinzugefügt haben.

Hinweis:Bevor Sie bestimmte Google-Dienste aufrufen können, müssen Sie Ihre App möglicherweise zuerst in der Google Developers Console registrieren. Eine Anleitung finden Sie in der entsprechenden Einführung für die von Ihnen verwendete API, z. B. für Google Drive oder Google Log-in.

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

Hier ist 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 Ihre App ein PendingResult-Objekt hat, kann sie angeben, ob die Anfrage als asynchroner oder synchroner Aufruf verarbeitet werden soll.

Tipp:Ihre App kann Leseanfragen in die Warteschlange stellen, auch wenn keine Verbindung zu den Google Play-Diensten besteht. So kann Ihre App beispielsweise Methoden aufrufen, um eine Datei aus Google Drive zu lesen, unabhängig davon, ob Ihre GoogleApiClient-Instanz bereits verbunden ist. Nachdem eine Verbindung hergestellt wurde, werden die in der Warteschlange befindlichen Leseanfragen ausgeführt. Schreibanfragen generieren einen Fehler, wenn Ihre App Schreibmethoden von Google Play-Diensten aufruft, während Ihr Google API-Client nicht verbunden ist.

Asynchrone Aufrufe verwenden

Wenn die Anfrage asynchron sein soll, rufe setResultCallback() auf PendingResult auf und gib eine Implementierung der Schnittstelle ResultCallback an. Hier ist beispielsweise eine 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 im onResult()-Callback ein Result-Objekt empfängt, wird es als Instanz der entsprechenden Unterklasse geliefert, wie in der von Ihnen verwendeten API angegeben, z. B. DriveApi.MetadataBufferResult.

Synchrone Aufrufe verwenden

Wenn der Code in einer genau definierten Reihenfolge ausgeführt werden soll, z. B. weil das Ergebnis eines Aufrufs als Argument für einen anderen benötigt wird, kannst du die Anfrage synchron machen, indem du await() auf PendingResult aufrufst. Dadurch wird der Thread blockiert und das Result-Objekt wird zurückgegeben, wenn die Anfrage abgeschlossen ist. Dieses Objekt wird als Instanz der entsprechenden Unterklasse geliefert, wie in der von Ihnen verwendeten API angegeben, z. B. DriveApi.MetadataBufferResult.

Da der Aufruf von await() den Thread blockiert, bis das Ergebnis eintrifft, sollte Ihre App niemals synchrone Anfragen an Google APIs im UI-Thread senden. Ihre App kann mit einem AsyncTask-Objekt einen neuen Thread erstellen und über diesen Thread die synchrone Anfrage senden.

Im folgenden Beispiel wird gezeigt, wie eine Dateianfrage an Google Drive als synchroner Aufruf gesendet wird:

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

private class GetFileTask extends AsyncTask<String, Void, Void> {
    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 Mobilgeräten und Wearables ausgeführt werden. Die API besteht aus einer Reihe von Datenobjekten, die das System senden und synchronisieren kann, sowie Listenern, die Ihre Apps über eine Datenebene ü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 verbunden ist und die Wear OS-Companion-App auf dem Gerät installiert ist.

Wearable API als eigenständige API verwenden

Wenn Ihre App die Wearable API, aber keine anderen Google APIs verwendet, können Sie diese API hinzufügen, indem Sie die Methode addApi() aufrufen. Im folgenden Beispiel wird gezeigt, wie Sie Ihrer GoogleApiClient-Instanz die Wearable API 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.

Im folgenden Beispiel wird gezeigt, wie Sie feststellen, 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 Ihre App neben anderen Google APIs auch die Wearable API verwendet, rufen Sie die Methode addApiIfAvailable() auf und geben Sie die Wearable API an, um zu prüfen, ob sie verfügbar ist. Mit dieser Prüfung kann Ihre App Fälle, in denen die API nicht verfügbar ist, reibungslos bewältigen.

Im folgenden Beispiel wird gezeigt, wie Sie auf die Wearable API und die 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 GoogleApiClient eine Verbindung zu Google Drive herstellen, ohne eine Verbindung zur Wearable API herzustellen, wenn diese nicht verfügbar ist. Nachdem Sie Ihre GoogleApiClient-Instanz verbunden haben, prüfen Sie, ob die Wearable API verfügbar ist, bevor Sie API-Aufrufe ausführen:

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

API-Verbindungsfehler ignorieren

Wenn du addApi() aufrufst und der GoogleApiClient keine Verbindung zu dieser API herstellen kann, schlägt der gesamte Verbindungsvorgang für diesen Client fehl und der onConnectionFailed()-Callback wird ausgelöst.

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

Da APIs, die mit addApiIfAvailable() hinzugefügt wurden, nicht immer in der verbundenen GoogleApiClient-Instanz vorhanden sind, sollten Sie Aufrufe dieser APIs schützen, indem Sie eine Prüfung mit hasConnectedApi() hinzufügen. Wenn Sie wissen möchten, warum die Verbindung zu einer bestimmten API nicht hergestellt werden konnte, obwohl der gesamte Verbindungsvorgang für den Client erfolgreich war, rufen Sie getConnectionResult() auf und rufen Sie den Fehlercode aus dem Objekt ConnectionResult ab. Wenn dein Client eine API aufruft, ohne mit dem Client verbunden zu sein, 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 dem Einholen der OAuth-Einwilligung fehlschlägt. Bereiche, die mit addScope() hinzugefügt werden, werden dagegen immer angefordert.

Manuell verwaltete Verbindungen

Im größten 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, von Ihrer Android-App aus 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 sollten:

  • Auf Google APIs außerhalb einer Aktivität zugreifen oder die Kontrolle über die API-Verbindung behalten
  • Umgang mit Verbindungsfehlern anpassen

In diesem Abschnitt finden Sie 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 erhalten Callbacks als Antwort auf die asynchrone Methode connect(), wenn die Verbindung zu den Google Play-Diensten erfolgreich hergestellt wird, 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 App aufrufen. Im Aktivitätskontext empfiehlt es sich, connect() in der onStart()-Methode der Aktivität und disconnect() in der onStop()-Methode der Aktivität aufzurufen. Die Methoden connect() und disconnect() werden automatisch aufgerufen, wenn eine automatisch verwaltete Verbindung verwendet wird.

Wenn Sie GoogleApiClient verwenden, um eine Verbindung zu APIs herzustellen, für die eine Authentifizierung erforderlich ist, z. B. Google Drive oder Google Play Spiele, schlägt der erste Verbindungsversuch mit hoher Wahrscheinlichkeit fehl und Ihre App erhält einen onConnectionFailed()-Aufruf mit dem Fehler SIGN_IN_REQUIRED, weil das Nutzerkonto nicht angegeben wurde.

Umgang mit Verbindungsfehlern

Wenn Ihre App einen Aufruf des onConnectionFailed()-Callbacks erhält, sollten Sie hasResolution() für das bereitgestellte ConnectionResult-Objekt aufrufen. Wenn „true“ zurückgegeben wird, kann Ihre App den Nutzer auffordern, sofort Maßnahmen zur Behebung des Fehlers zu ergreifen, indem startResolutionForResult() auf das Objekt ConnectionResult aufgerufen wird. Die Methode startResolutionForResult() verhält sich in dieser Situation genauso wie startActivityForResult() und startet eine Aktivität, die dem Kontext angemessen ist und dem Nutzer hilft, den Fehler zu beheben (z. B. eine Aktivität, die dem Nutzer hilft, ein Konto auszuwählen).

Wenn hasResolution() „falsch“ zurückgibt, sollte Ihre App GoogleApiAvailability.getErrorDialog() aufrufen und den Fehlercode an diese Methode übergeben. Dies gibt eine von Google Play-Diensten bereitgestellte Dialog zurück, die dem Fehler entspricht. Das Dialogfeld kann einfach eine Meldung mit einer Erklärung des Fehlers enthalten oder eine Aktion, mit der eine Aktivität gestartet wird, die den Fehler beheben kann (z. B. wenn der Nutzer eine neuere Version der Google Play-Dienste installieren muss).

Die Callback-Methode für 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 Dialogfeld von startResolutionForResult() abgeschlossen oder die Meldung von GoogleApiAvailability.getErrorDialog() geschlossen hat, wird für Ihre Aktivität der Callback onActivityResult() mit dem Ergebniscode RESULT_OK gesendet. Ihre App 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 obigen Code ist Ihnen wahrscheinlich der boolesche Wert mResolvingError aufgefallen. So wird der App-Status während der Fehlerbehebung durch den Nutzer überwacht, um wiederholte Versuche zur Behebung desselben Fehlers zu vermeiden. Beispielsweise kann der Nutzer den Bildschirm drehen, während das Dialogfeld für die Kontoauswahl angezeigt wird, um den SIGN_IN_REQUIRED-Fehler zu beheben. Dadurch wird Ihre Aktivität neu erstellt und die Methode onStart() wird noch einmal aufgerufen, was wiederum einen erneuten Aufruf von connect() zur Folge hat. Dies führt zu einem weiteren Aufruf von startResolutionForResult(), wodurch ein weiteres Dialogfeld für die Kontoauswahl vor dem vorhandenen Dialogfeld erstellt wird.

Dieser boolesche Wert erfüllt seinen Zweck nur, wenn er über Aktivitätsinstanzen hinweg beibehalten wird. Im nächsten Abschnitt wird beschrieben, wie Sie den Status der Fehlerbehandlung Ihrer App bei anderen Nutzeraktionen oder Ereignissen auf dem Gerät beibehalten.

Status bei der Fehlerbehebung beibehalten

Damit der Code in onConnectionFailed() nicht ausgeführt wird, während ein vorheriger Versuch zur Behebung eines Fehlers noch läuft, müssen Sie eine boolesche Variable beibehalten, die erfasst, ob in Ihrer App bereits versucht wird, einen Fehler zu beheben.

Wie im Codebeispiel oben gezeigt, sollte Ihre App jedes Mal, wenn sie startResolutionForResult() aufruft oder das Dialogfeld von GoogleApiAvailability.getErrorDialog() anzeigt, einen booleschen Wert auf true festlegen. Wenn Ihre App dann RESULT_OK im Callback onActivityResult() erhält, setzen Sie den booleschen Wert auf false.

Wenn Sie den booleschen Wert bei Neustarts der Aktivität im Blick behalten möchten (z. B. wenn der Nutzer das Display dreht), 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 Status während 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.