Accéder aux API Google avec GoogleApiClient (obsolète)

Vous pouvez utiliser GoogleApiClient ("Client API Google") objet permettant d'accéder aux API Google fournies dans la bibliothèque de services Google Play (Google Sign-In, Jeux et Drive, par exemple). Le client API Google fournit un point d'entrée commun aux services Google Play et gère le réseau entre l'appareil de l'utilisateur et chaque service Google.

Cependant, la nouvelle interface GoogleApi et ses implémentations sont plus faciles à sont le moyen privilégié pour accéder aux API des services Play. Consultez la page Accéder aux API Google.

Ce guide vous explique comment:

  • Gérez automatiquement votre connexion aux services Google Play.
  • Effectuer des appels d'API synchrones et asynchrones vers l'un des services Google Play
  • Gérer manuellement votre connexion aux services Google Play dans les rares cas où cela se produit nécessaires. Pour en savoir plus, consultez Connexions gérées manuellement.
Figure 1: Illustration montrant comment le client Google APIs fournit un permettant de se connecter aux services Google Play disponibles et de les appeler, Google Play Jeux et Google Drive.

Pour commencer, vous devez d'abord installer la bibliothèque de services Google Play (version 15 ou ultérieure) pour votre SDK Android. Si vous ne l'avez pas déjà fait, suivez les instructions fournies dans l'article Configurez le SDK des services Google Play.

Démarrer une connexion gérée automatiquement

Une fois votre projet associé à la bibliothèque des services Google Play, créez une instance de GoogleApiClient à l'aide de GoogleApiClient.Builder les API dans le onCreate() . La GoogleApiClient.Builder fournit des méthodes vous permettant de spécifier les API Google à utiliser et les Champs d'application OAuth 2.0. Voici un exemple de code qui crée Instance GoogleApiClient qui se connecte au service Google Drive:

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

Vous pouvez ajouter plusieurs API et plusieurs champs d'application au même GoogleApiClient en ajoutant des appels supplémentaires à addApi() et addScope().

Important:Si vous ajoutez l'API Wearable avec d'autres API à une GoogleApiClient, il est possible que vous rencontriez des erreurs de connexion client sur les appareils si l'application Wear OS n'est pas installée. À éviter les erreurs de connexion, appelez la méthode addApiIfAvailable() et transmettez l'API Wearable pour permettre à votre client de gérer de façon optimale les éléments API. Pour en savoir plus, consultez Accéder à l'API Wearable.

Pour démarrer une connexion gérée automatiquement, vous devez spécifier un l'implémentation de OnConnectionFailedListener pour recevoir des erreurs de connexion non résolus. Lorsque votre compte GoogleApiClient tente de se connecter aux API Google, elle va automatiquement pour tenter de résoudre les échecs de connexion pouvant être résolus (par exemple, si vous devez mettre à jour les services Google Play). Si une erreur qui ne peut être résolu, vous recevrez un appel au onConnectionFailed()

Vous pouvez également spécifier une implémentation facultative pour l'interface ConnectionCallbacks si votre application doit savoir quand le automatiquement gérée est établie ou suspendue. Par exemple, si votre application effectue des appels pour écrire des données dans les API Google. qu'après l'appel de la méthode onConnected().

Voici un exemple d'activité qui implémente les interfaces de rappel et ajoute au client API Google:

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

        // ...
    }
}

Votre instance GoogleApiClient se connectera automatiquement après votre activité appelle onStart() et déconnectez-vous après avoir appelé onStop(). Votre application peut immédiatement commencer les requêtes de lecture aux API Google après avoir créé GoogleApiClient, sans en attendant que la connexion soit terminée.

Communiquer avec les services Google

Une fois connecté, votre client peut effectuer des appels de lecture et d'écriture à l'aide des API spécifiques au service pour pour lesquels votre application est autorisée, comme spécifié par les API et les niveaux d'accès que vous avez ajoutés à votre Instance GoogleApiClient.

Remarque:Avant d'appeler des services Google spécifiques, vous devrez peut-être enregistrer votre dans la Google Developers Console. Pour obtenir des instructions, reportez-vous aux instructions de démarrage rapide de l'API que vous utilisez, par exemple Google Drive ou Google Sign-In :

Lorsque vous effectuez une requête de lecture ou d'écriture à l'aide de GoogleApiClient, le client API renvoie un objet PendingResult qui représente la requête. Cela se produit immédiatement, avant que la requête ne soit envoyée au service Google que votre application appelle.

Par exemple, voici une requête permettant de lire un fichier de Google Drive qui fournit un Objet PendingResult:

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

Une fois que votre application dispose d'un objet PendingResult, votre application peut ensuite spécifier si la requête est traitée comme un appel asynchrone ou comme un appel synchrone.

Remarque:Votre application peut mettre les requêtes de lecture en file d'attente lorsqu'elle n'est pas connectée aux services Google Play. Pour Par exemple, votre application peut appeler des méthodes pour lire un fichier à partir de Google Drive, que votre instance GoogleApiClient soit déjà connectée ou non. Une fois la connexion établie, les requêtes de lecture mises en file d'attente s'exécutent. Les requêtes d'écriture génèrent une erreur si votre application appelle Méthodes d'écriture des services Google Play lorsque votre client API Google n'est pas connecté

Utiliser des appels asynchrones

Pour rendre la requête asynchrone, appelez setResultCallback() sur le PendingResult et fournissez la mise en œuvre ResultCallback. Pour exemple, voici la requête exécutée de manière asynchrone:

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.
            // ...
        }
    });
}

Lorsque votre application reçoit un objet Result dans le rappel onResult(), il est fourni en tant qu'instance de la sous-classe appropriée, comme spécifié par l'API que vous utilisez, tels que DriveApi.MetadataBufferResult

Utiliser des appels synchrones

Si vous voulez que votre code s'exécute dans un ordre strictement défini, peut-être parce que le résultat d'une est nécessaire comme argument d'un autre, vous pouvez rendre votre requête synchrone en appelant await() sur le PendingResult Cela bloque le thread et renvoie l'objet Result lorsque la requête est terminée. Cet objet est fourni en tant qu'instance de la sous-classe appropriée, comme spécifié par l'API que vous utilisez, par exemple DriveApi.MetadataBufferResult

Parce que le fait d'appeler await() bloque le thread jusqu'à l'arrivée du résultat, votre application ne doit jamais envoyer de requêtes synchrones aux API Google sur le thread UI. Votre application peut créer un thread à l'aide d'un objet AsyncTask et utiliser ce thread pour effectuer la requête synchrone.

L'exemple suivant montre comment envoyer une demande de fichier à Google Drive sous la forme d'un appel synchrone:

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

Accéder à l'API Wearable

L'API Wearable fournit un canal de communication pour les applications qui s'exécutent sur des appareils portables et des accessoires connectés. L'API est constituée d'un ensemble d'objets de données que le système peut envoyer et synchroniser. qui notifient vos applications d'événements importants à l'aide d'une couche de données. La L'API Wearable est disponible sur les appareils équipés d'Android 4.3 (niveau d'API 18) ou version ultérieure, et si les conditions suivantes sont remplies : un accessoire connecté est connecté et l'application associée Wear OS est installé sur l'appareil.

Utiliser l'API Wearable de manière autonome

Si votre application utilise l'API Wearable, mais pas d'autres API Google, vous pouvez ajouter cette API en en appelant la méthode addApi(). L'exemple suivant montre comment ajouter le API Wearable à votre instance GoogleApiClient:

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

Dans les cas où l'API Wearable n'est pas disponible, les demandes de connexion si l'API Wearable échoue avec API_UNAVAILABLE code d'erreur.

L'exemple suivant montre comment déterminer si l'API Wearable est disponible:

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

Utiliser l'API Wearable avec d'autres API Google

Si votre application utilise l'API Wearable en plus d'autres API Google, appelez la méthode addApiIfAvailable() et transmettez l'API Wearable pour vérifier si elle est disponible. Vous pouvez utiliser cette vérification pour aider votre application à gérer correctement les cas où l'API n'est pas disponible.

L'exemple suivant montre comment accéder à l'API Wearable avec le API Drive:

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

Dans l'exemple ci-dessus, le GoogleApiClient peut se connecter avec Google Drive sans se connecter à l'API Wearable si elle n'est pas disponible. Après vous connectez votre GoogleApiClient assurez-vous que l'API Wearable est disponible avant d'effectuer les appels d'API:

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

Ignorer les échecs de connexion à l'API

Si vous appelez addApi() et que GoogleApiClient ne parvient pas à se connecte à cette API, l'ensemble de l'opération de connexion pour ce client échoue et déclenche le rappel onConnectionFailed().

Vous pouvez enregistrer un échec de connexion à l'API afin qu'il soit ignoré en utilisant addApiIfAvailable() Si une API ajoutée avec Échec de la connexion de addApiIfAvailable() en raison d'une erreur non récupérable (comme API_UNAVAILABLE pour Wear), cette API est supprimée de votre GoogleApiClient et le client passe à pour se connecter à d'autres API. Toutefois, si une connexion API échoue avec une erreur récupérable (par exemple, l'intent de résolution du consentement OAuth), l'opération de connexion client échoue. Quand ? à l'aide d'une connexion gérée automatiquement, le GoogleApiClient tentera pour résoudre ces erreurs lorsque cela est possible. En cas d'utilisation d'une connexion gérée manuellement un ConnectionResult contenant un intent de résolution est envoyé au rappel onConnectionFailed(). API les échecs de connexion ne sont ignorés que s'ils n'ont pas été résolus et que l'API a été ajoutée avec addApiIfAvailable(). Pour découvrir comment implémenter un échec de connexion manuel consultez la section Gérer les échecs de connexion.

Étant donné que les API Il est possible que addApiIfAvailable() ne soit pas toujours présent dans le réseau GoogleApiClient, vous devez protéger les appels vers ces API en ajoutant une vérification avec hasConnectedApi(). Pour savoir pourquoi un une API spécifique n'a pas réussi à se connecter lorsque l'ensemble de l'opération de connexion a réussi pour le client, appelez getConnectionResult() et récupérez le code d'erreur à partir de objet ConnectionResult. Si votre client appelle une API alors qu'elle ne l'est pas, connecté au client, l'appel échoue avec API_NOT_AVAILABLE code d'état.

Si l'API que vous ajoutez via addApiIfAvailable() nécessite un ou ou d'autres champs d'application, ajoutez-les en tant que paramètres l'appel de méthode addApiIfAvailable() plutôt que d'utiliser la addScope(). Les niveaux d'accès ajoutés à l'aide de cette approche ne peuvent pas être demandés si l'API la connexion échoue avant d'obtenir le consentement OAuth, alors que les champs d'application ajoutés avec Les addScope() sont toujours demandées.

Connexions gérées manuellement

Dans ce guide, la majeure partie de ce guide vous explique comment utiliser enableAutoManage pour lancer une connexion gérée automatiquement avec les erreurs résolues automatiquement. Dans presque Dans tous les cas, il s'agit du moyen le plus simple et le plus efficace de vous connecter aux API Google Application Android. Cependant, il est parfois utile d'utiliser un connexion gérée manuellement aux API Google dans votre application:

  • Pour accéder aux API Google en dehors d'une activité ou garder le contrôle de l'API connexion
  • Pour personnaliser la gestion et la résolution des erreurs de connexion

Cette section fournit des exemples et d'autres cas d'utilisation avancée.

Démarrer une connexion gérée manuellement

Pour établir une connexion gérée manuellement à GoogleApiClient, vous devez : spécifier une implémentation pour les interfaces de rappel ; ConnectionCallbacks et OnConnectionFailedListener. Ces interfaces reçoivent des rappels en réponse à l'appel d'API connect() lorsque connexion aux services Google Play aboutit, échoue ou est suspendue.

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

Si vous gérez manuellement une connexion, vous devez appeler la méthode connect() et disconnect() aux bons moments du cycle de vie de votre application. Dans une activité contexte, il est recommandé d'appeler connect() dans le onStart() de votre activité et disconnect() dans la méthode onStop() de votre activité. Les connect() et Méthodes disconnect() sont appelés automatiquement lors de l'utilisation d'une connexion gérée automatiquement.

Si vous utilisez GoogleApiClient pour vous connecter aux API qui nécessitent comme Google Drive ou Google Play Jeux, il est fort probable votre première tentative de connexion échouera et votre application recevra un appel à onConnectionFailed() avec le SIGN_IN_REQUIRED s'affiche, car le compte utilisateur n'a pas été spécifié.

Gérer les échecs de connexion

Lorsque votre application reçoit un appel au onConnectionFailed() vous devez appeler hasResolution() sur le ConnectionResult fourni . Si la valeur est "true", votre application peut demander à l'utilisateur d'agir immédiatement pour résoudre l'erreur en appel de startResolutionForResult() en cours sur l'objet ConnectionResult. La méthode startResolutionForResult() se comporte de la même manière que startActivityForResult() dans cette situation, et lance une activité adaptée au contexte qui aide l'utilisateur à résoudre l'erreur (comme une activité qui l'aide à sélectionnez un compte).

Si hasResolution() renvoie "false", votre application doit appeler GoogleApiAvailability.getErrorDialog() en transmettant le code d'erreur à cette méthode. Cela renvoie un Dialog fourni par Google Play adaptés à l'erreur. La boîte de dialogue peut simplement fournir un message expliquant l'erreur, ou il peut également fournir une action pour lancer une activité permettant de résoudre l'erreur (par exemple, lorsque l'utilisateur doit installer une version plus récente des services Google Play).

Par exemple, votre La méthode de rappel onConnectionFailed() devrait maintenant se présenter comme suit:

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

Une fois que l'utilisateur a rempli la boîte de dialogue fournie par startResolutionForResult() ou ignore le message fourni par GoogleApiAvailability.getErrorDialog(), votre activité reçoit onActivityResult() avec la commande RESULT_OK code de résultat. Votre application peut alors appeler connect(). Exemple :

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

Dans le code ci-dessus, vous avez probablement remarqué la valeur booléenne mResolvingError. Cela permet de garder une trace l'état de l'application pendant que l'utilisateur résout l'erreur, afin d'éviter les tentatives répétées de résolution de la même erreur. . Par exemple, alors que la boîte de dialogue de l'outil de sélection de comptes s'affiche pour aider l'utilisateur à résoudre le problème SIGN_IN_REQUIRED s'affiche, l'utilisateur peut faire pivoter l'écran. Cela recrée votre activité et provoque onStart() doit être rappelé, ce qui appelle connect() Ce génère un autre appel à startResolutionForResult() ce qui crée une autre boîte de dialogue de sélection de compte devant celle existante.

Cette valeur booléenne sert à servir uniquement si elle persiste dans les instances d'activité. La section suivante explique comment maintenir l'état de traitement des erreurs de votre application malgré les autres actions de l'utilisateur ou des événements qui se produisent sur l’appareil.

Maintenir l'état pendant la résolution d'une erreur

Pour éviter d'exécuter le code dans onConnectionFailed() alors qu'une précédente tentative de résolution d'une erreur est en cours, vous devez conserver une valeur booléenne qui détermine si votre application essaie déjà de résoudre une erreur.

Comme indiqué dans l'exemple de code ci-dessus, votre application doit définir une valeur booléenne sur true chaque fois qu'elle appelle startResolutionForResult() ou affiche la boîte de dialogue GoogleApiAvailability.getErrorDialog() Ensuite, lorsque votre application reçoit RESULT_OK dans onActivityResult() , définissez la valeur booléenne sur false.

Pour suivre la valeur booléenne lors des redémarrages d'activité (par exemple, lorsque l'utilisateur fait pivoter l'écran), enregistrer la valeur booléenne dans les données d'instance enregistrées de l'activité à l'aide de onSaveInstanceState():

private static final String STATE_RESOLVING_ERROR = "resolving_error";

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

Ensuite, récupérez l'état enregistré onCreate():

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

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

Vous pouvez maintenant exécuter votre application en toute sécurité et vous connecter manuellement aux services Google Play.