Appeler des API backend à partir d'un client Android

Cette page décrit comment un client Android appelle une API backend conçue à l'aide de Cloud Endpoints Frameworks pour App Engine.

Générer la bibliothèque cliente

Votre client Android requiert la bibliothèque cliente générée à partir de l'API backend qu'il utilise. Si vous ne disposez pas encore d'une bibliothèque cliente, reportez-vous à la section Générer une bibliothèque cliente pour en savoir plus. Ce document contient des étapes expliquant comment ajouter la bibliothèque cliente au projet du client Android.

Mettre en place le projet

Dans les instructions ci-dessous, vous utilisez Android Studio. Si ce n'est pas déjà fait, vous devez configurer Android Studio pour être compatible avec un client utilisant les frameworks.

Configurer le projet

Dans Android Studio, votre projet utilise le fichier build.gradle pour les dépendances et d'autres paramètres. Par défaut, Android Studio crée un fichier build.gradle parent au niveau du projet et un fichier spécifique à l'application Android dans le module Android. Ces instructions concernent le fichier build.gradle spécifique à l'application du module Android.

Pour configurer build.gradle, procédez comme suit :

  1. Double-cliquez sur build.gradle pour l'ouvrir.

  2. Modifiez ce fichier pour qu'il contienne les lignes suivantes :

    buildscript {
        repositories {
            mavenCentral()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:1.0.0'
        }
    }
    apply plugin: 'com.android.application'
    
    repositories {
        mavenCentral()
        mavenLocal()
    }
    
    android {
        compileSdkVersion 26
    
        defaultConfig {
            applicationId "com.mycompany.myapp"
            minSdkVersion 17
            targetSdkVersion 26
            versionCode 1
            versionName "1.0"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
        packagingOptions {
            exclude 'META-INF/DEPENDENCIES'
        }
    }
    
    dependencies {
        implementation 'com.android.support:appcompat-v7:26.1.0'
        implementation 'com.android.support.constraint:constraint-layout:1.1.3'
        // BEGIN Google APIs
        // Play Services will validate the application prior to allowing OAuth2 access.
        implementation 'com.google.android.gms:play-services-auth:16.0.0'
        implementation 'com.google.android.gms:play-services-identity:16.0.0'
        // The following lines implement maven imports as defined at:
        // https://github.com/googleapis/google-api-java-client/wiki/Setup-Instructions
        // Add the Google API client library.
        implementation('com.google.api-client:google-api-client:1.28.0') {
            // Exclude artifacts that the Android SDK/Runtime provides.
            exclude(group: 'xpp3', module: 'xpp3')
            exclude(group: 'org.apache.httpcomponents', module: 'httpclient')
            exclude(group: 'junit', module: 'junit')
            exclude(group: 'com.google.android', module: 'android')
        }
        // Add the Android extensions for the Google API client library.
        // This will automatically include play services as long as you have download that library
        // from the Android SDK manager.
        // Add the Android extensions for the Google API client library.
        implementation(group: 'com.google.api-client', name: 'google-api-client-android', version: '1.25.0') {
                   // Exclude play services, since we're not using this yet.
                  exclude(group: 'com.google.android.gms:play-services', module: 'google-play-services')
        }
        // END Google APIs
        // The following client libraries make HTTP/JSON on Android easier.
        // Android extensions for Google HTTP Client.
        implementation('com.google.http-client:google-http-client-android:1.21.0') {
            exclude(group: 'com.google.android', module: 'android')
        }
        implementation 'com.google.http-client:google-http-client-gson:1.21.0'
        // This is used by the Google HTTP client library.
        implementation 'com.google.guava:guava:18.0+'
        implementation files('libs/echo-v1-1.25.0-SNAPSHOT.jar')
    }
    
    

    Remplacez com.mycompany.myapp par vos propres valeurs.

  3. Cliquez sur File > Save All (Fichier > Tout enregistrer), puis quittez Android Studio et redémarrez-le.

Ajouter la bibliothèque cliente au projet

Pour ajouter la bibliothèque cliente au projet Android, procédez comme suit :

  1. Ajoutez un répertoire /libs à votre projet s'il n'en possède pas déjà un. Ce répertoire est appairé au répertoire /src.

  2. Copiez la bibliothèque cliente générée à partir de l'API backend dans /libs.

  3. Cliquez avec le bouton droit sur la bibliothèque que vous venez d'ajouter, puis sélectionnez Add As Library (Ajouter en tant que bibliothèque) pour l'ajouter à votre projet.

Créer l'objet de service

Dans le code de votre projet, vous devez utiliser un objet de service pour envoyer des requêtes à l'API backend. Pour les requêtes unauthenticated, construisez l'objet de service comme suit:

BACKEND_API_NAME.Builder builder = new BACKEND_API_NAME.Builder(
    NetHttpTransport(), new GsonFactory(), null);
service = builder.build();

Remplacez BACKEND_API_NAME par le nom de votre API backend.

Appeler l'API backend

Dans votre projet, appelez l'API à l'aide de l'objet de service. Exemple :

ScoreCollection scores = service.scores().list().execute();

Dans cet extrait de code, vous demandez la liste de tous les objets Score figurant sur le serveur. Si la méthode list requiert des paramètres ou un corps de requête, vous les fournissez dans la commande. Android Studio permet l'exécution du code afin d'identifier les appels de méthodes disponibles et leurs paramètres requis.

Il est important de noter que, comme les appels d'API donnent lieu à des requêtes sur le réseau, vous devez les effectuer dans leur propre thread. (Cette exigence a été ajoutée aux versions récentes d'Android, mais il s'agissait déjà d'une bonne pratique à suivre dans les versions antérieures). Pour ce faire, utilisez Thread ou AsyncTask. Exemple :

private class QueryScoresTask extends AsyncTask<Void, Void, ScoreCollection>{
  Context context;

  public QueryScoresTask(Context context) {
    this.context = context;
  }

  protected Scores doInBackground(Void... unused) {
    ScoreCollection scores = null;
    try {
      scores = service.scores().list().execute();
    } catch (IOException e) {
      Log.d("TicTacToe", e.getMessage(), e);
    }
    return scores;
  }

  protected void onPostExecute(ScoreCollection scores) {
    // Do something with the result.
  }
}

Effectuer des appels authentifiés

Les instructions suivantes ne concernent que le code client que vous devez ajouter. Elles partent du principe que vous avez déjà intégré la gestion de l'authentification par Endpoints Framework, comme décrit dans la documentation Authentifier les utilisateurs.

Si votre client Android effectue des appels vers un point de terminaison nécessitant une authentification, vous devez :

  • configurer votre client Android pour fournir des identifiants à l'objet de service ;
  • vous servir du sélecteur de compte pour permettre à l'utilisateur de choisir le compte de connexion.

Vous trouverez des informations détaillées dans les sections suivantes.

Configurer le client Android pour fournir des identifiants

Pour fonctionner avec les requêtes adressées à une API backend nécessitant une authentification, votre client Android doit obtenir les identifiants utilisateur et les transmettre à l'objet de service.

Pour obtenir les identifiants utilisateur et vous servir du sélecteur de compte, vous devez disposer des autorisations Android suivantes :

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

Pour obtenir les identifiants utilisateur, appelez GoogleAccountCredential.usingAudience comme suit :

// Inside your Activity class onCreate method
settings = getSharedPreferences(
    "TicTacToeSample", 0);
credential = GoogleAccountCredential.usingAudience(this,
    "server:client_id:1-web-app.apps.googleusercontent.com");

où le deuxième paramètre de l'appel correspond au préfixe server:client_id ajouté à l'ID client Web de l'API backend.

Exemple de code : obtenir des identifiants pour l'objet de service

Le code suivant montre comment obtenir des identifiants et les transmettre à l'objet de service :

// Inside your Activity class onCreate method
settings = getSharedPreferences("TicTacToeSample", 0);
credential = GoogleAccountCredential.usingAudience(this,
    "server:client_id:1-web-app.apps.googleusercontent.com");
setSelectedAccountName(settings.getString(PREF_ACCOUNT_NAME, null));

Tictactoe.Builder builder = new Tictactoe.Builder(
    NetHttpTransport(), new GsonFactory(),
    credential);
service = builder.build();

if (credential.getSelectedAccountName() != null) {
  // Already signed in, begin app!
} else {
  // Not signed in, show login window or request an account.
}

// setSelectedAccountName definition
private void setSelectedAccountName(String accountName) {
  SharedPreferences.Editor editor = settings.edit();
  editor.putString(PREF_ACCOUNT_NAME, accountName);
  editor.commit();
  credential.setSelectedAccountName(accountName);
  this.accountName = accountName;
}

L'exemple de code ci-dessus recherche les préférences partagées stockées par l'application Android et tente de trouver le nom du compte auquel l'utilisateur souhaite faire appel pour s'authentifier auprès de votre application. Si l'opération réussit, le code crée un objet identifiants et le transmet à votre objet de service. Ces identifiants permettent à votre application Android de transmettre le jeton approprié au backend.

Notez que l'exemple de code vérifie si l'application Android sait déjà quel compte utiliser ou non. Si c'est le cas, le flux logique peut continuer et exécuter directement l'application Android. Si l'application ne sait pas quel compte utiliser, elle affiche un écran de connexion ou invite l'utilisateur à choisir un compte.

Enfin, l'exemple crée un objet identifiants et le transmet à l'objet de service. Ces identifiants permettent à votre application Android de transmettre le jeton approprié à votre application Web App Engine.

Utiliser le sélecteur de compte

Android fournit un intent permettant de sélectionner un compte d'utilisateur. Vous pouvez en appeler un comme suit :

static final int REQUEST_ACCOUNT_PICKER = 2;

void chooseAccount() {
  startActivityForResult(credential.newChooseAccountIntent(),
      REQUEST_ACCOUNT_PICKER);
}

Voici un gestionnaire permettant d'interpréter le résultat de cet intent :

@Override
protected void onActivityResult(int requestCode, int resultCode,
   Intent data) {
 super.onActivityResult(requestCode, resultCode, data);
 switch (requestCode) {
   case REQUEST_ACCOUNT_PICKER:
     if (data != null && data.getExtras() != null) {
       String accountName =
           data.getExtras().getString(
               AccountManager.KEY_ACCOUNT_NAME);
       if (accountName != null) {
         setSelectedAccountName(accountName);
         SharedPreferences.Editor editor = settings.edit();
         editor.putString(PREF_ACCOUNT_NAME, accountName);
         editor.commit();
         // User is authorized.
       }
     }
     break;
  }
}

Tester un client Android sur un serveur de développement local

Vous pouvez tester votre client avec une API backend exécutée sur les serveurs de production App Engine à tout moment et sans y apporter de modification. Toutefois, si vous souhaitez tester votre client avec une API backend exécutée sur un serveur de développement local, vous devez modifier la ligne de code figurant dans le client afin qu'elle pointe vers l'adresse IP de la machine qui exécute ce serveur.

Pour effectuer les modifications nécessaires et tester votre client à l'aide d'un serveur de développement local, procédez comme suit :

  1. Notez l'adresse IP de la machine qui exécute le serveur de développement local. Vous en aurez besoin lorsque vous ajouterez du code au client Android.

  2. Démarrez le serveur de développement local, comme décrit dans la section Tester une API en local.

  3. Dans votre projet client Android Studio, localisez le code qui fournit le descripteur vers le service de l'API backend. En règle générale, ce code utilise un objet Builder pour configurer la requête API.

  4. Remplacez l'URL racine de l'objet Builder (il s'agit de l'URL à laquelle le client Android se connecte lors de l'appel à l'API backend) en ajoutant la ligne suivante :

    yourBuilderObject.setRootUrl("http://YOUR_MACHINE_IP_ADDRESS:8080/_ah/api");
    

    Exemple :

    public static Helloworld getApiServiceHandle(@Nullable GoogleAccountCredential credential) {
      // Use a builder to help formulate the API request.
      Helloworld.Builder helloWorld = new Helloworld.Builder(AppConstants.HTTP_TRANSPORT,
          AppConstants.JSON_FACTORY,credential);
    
      helloWorld.setRootUrl("http://YOUR_MACHINE_IP_ADDRESS:8080/_ah/api");
      return helloWorld.build();
    }
    

    Remplacez YOUR_MACHINE_IP_ADDRESS par l'adresse IP de votre système.

  5. Recréez le projet du client Android.

  6. Si vous souhaitez exécuter votre application cliente sur un émulateur AVD, procédez comme suit :

    1. Dans Android Studio, sélectionnez Tools > Android > AVD Manager (Outils > Android > Gestionnaire AVD). Démarrez un fichier AVD existant ou, sinon, créez-en un, puis démarrez-le.
    2. Accédez à Run > Debug YOUR_PROJECT_NAME (Exécuter > Déboguer "nom du projet"), où YOUR_PROJECT_NAME représente le nom de votre projet Google Cloud.
    3. Lorsque vous êtes invité à choisir un appareil, sélectionnez votre AVD.
    4. Testez votre client.
  7. Si vous souhaitez exécuter votre application cliente sur un appareil Android physique, procédez comme suit :

    1. Assurez-vous que le débogage est activé sur votre appareil Android.
    2. Dans Android Studio, sélectionnez Run (Exécuter) > Debug YOUR_PROJECT_NAME (Déboguer "nom du projet").
    3. Lorsque vous êtes invité à choisir un appareil, sélectionnez votre appareil Android physique.
    4. Testez votre client.

Exemple de code source client

Pour obtenir un exemple de code, consultez la section Exemple Android Cloud Endpoints v2.0.