Chiamate alle API di backend da un client Android

Questa pagina descrive come un client Android chiama un'API di backend creata con i framework Cloud Endpoints per App Engine.

Generazione della libreria client

Il client Android richiede la libreria client generata dall'API di backend utilizzata dal client. Se non hai ancora la libreria client, consulta Generazione di una libreria client per maggiori dettagli. Il documento contiene alcuni passaggi che spiegano come aggiungere libreria client al progetto client Android.

Configurazione del progetto

In queste istruzioni, usi Android Studio. Se non l'hai ancora fatto, devi configurare Android Studio in modo da supportare un client che utilizzi i framework.

Configurazione del progetto

In Android Studio, il progetto utilizza il file build.gradle per le dipendenze e altre impostazioni. Per impostazione predefinita, Android Studio crea un'istanza principale a livello di progetto build.gradle e uno specifico dell'app per Android nel modulo per Android. Queste istruzioni riguardano il build.gradle specifico dell'app nel modulo Android.

Per configurare build.gradle:

  1. Fai doppio clic su build.gradle per aprirlo.

  2. Modifica questo file in modo che contenga le seguenti righe:

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

    Sostituisci com.mycompany.myapp con i tuoi valori.

  3. Fai clic su File > Salva tutto, quindi esci da Android Studio e riavvialo.

Aggiunta della libreria client al progetto in corso...

Per aggiungere la libreria client al progetto Android:

  1. Aggiungi una directory /libs al progetto, se non ne ha già una. È un peer della directory /src.

  2. Copia la libreria client generata dall'API di backend in /libs.

  3. Fai clic con il pulsante destro del mouse sulla libreria appena aggiunta, quindi seleziona Aggiungi come raccolta per del tuo progetto.

Creazione dell'oggetto di servizio

Nel codice del progetto, devi utilizzare un oggetto di servizio per effettuare richieste all'API di backend. Per le richieste non autenticate, costruisci l'oggetto di servizio come che segue:

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

Sostituisci BACKEND_API_NAME con il nome dell'API di backend.

Chiamata all'API backend

Nel progetto, chiama l'API utilizzando l'oggetto di servizio. Ad esempio:

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

In questo snippet, richiedi un elenco di tutti gli oggetti Score sul server. Se list richiede parametri o un corpo della richiesta, devi fornire questi parametri nel comando. Android Studio consente il completamento del codice per l'identità delle chiamate ai metodi disponibili e i relativi parametri obbligatori.

È importante notare che, poiché le chiamate API generano richieste sulla rete, devi effettuare le richieste in un thread dedicato. Questo requisito è stato aggiunto alle versioni recenti di Android, ma è una best practice anche versions.) Per farlo, puoi usare un Thread o AsyncTask. Ad esempio:

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

Effettuare chiamate autenticate

Queste istruzioni riguardano solo la codifica client che devi aggiungere. Si presume che tu abbia già aggiunto il supporto dei framework di endpoint per l'autenticazione come descritto in Autenticazione degli utenti.

Se il client Android effettua chiamate a un endpoint che richiede dell'autenticazione, devi:

  • Configura il tuo client Android in modo che fornisca le credenziali all'oggetto del servizio.
  • Utilizza il selettore per supportare la scelta dell'utente degli account di accesso.

Le sezioni seguenti forniscono dettagli.

Configurare il client Android per fornire le credenziali

Per supportare le richieste a un'API di backend che richiede l'autenticazione, il client Android deve recuperare le credenziali utente e passarle all'oggetto servizio.

Recupero delle credenziali utente e utilizzo selettore account richiede i seguenti requisiti Autorizzazioni Android:

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

Per ottenere le credenziali utente, chiama GoogleAccountCredential.usingAudience come segue:

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

dove il secondo parametro della chiamata è il prefisso server:client_id preposto all'ID client web dell'API di backend.

Codice di esempio: recupero delle credenziali per l'oggetto di servizio

Il codice seguente mostra come ottenere le credenziali e passarle all'oggetto servizio:

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

Il codice di esempio precedente cerca le preferenze condivise memorizzate dall'app Android e tenta di trovare il nome dell'account che l'utente vuole utilizzare per autenticarsi nella tua applicazione. In caso di esito positivo, il codice crea una credenziale e lo passa all'oggetto di servizio. Queste credenziali consentono ai tuoi L'app per Android passa il token appropriato al tuo backend.

Tieni presente che il codice di esempio controlla se l'app per Android sa già quale account utilizzare. In questo caso, il flusso logico può continuare ed eseguire l'app per Android. Se l'app non sa quale account utilizzare, visualizza una schermata di accesso o chiede all'utente di scegliere un account.

Infine, l'esempio crea un oggetto credenziali e lo passa all'oggetto servizio. Queste credenziali consentono alla tua app per Android di trasmettere il token appropriato alla tua app web App Engine.

Utilizzare il selettore account

Android fornisce un'intent per selezionare un account utente. Puoi invocarlo come segue:

static final int REQUEST_ACCOUNT_PICKER = 2;

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

Qui viene mostrato un gestore per l'interpretazione del risultato di questo 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;
  }
}

Test di un client Android su un server di sviluppo locale

Puoi testare il client con un'API di backend in esecuzione in produzione su App Engine in qualsiasi momento senza apportare modifiche. Tuttavia, se vuoi per testare il tuo client su un'API di backend in esecuzione sul Occorre modificare la riga di codice nel client in modo che punti all'IP della macchina che esegue il server di sviluppo locale.

Per apportare le modifiche richieste ed eseguire i test utilizzando il server di sviluppo locale:

  1. Annota l'indirizzo IP della macchina che esegue l'istanza locale di sviluppo software perché ti serve quando aggiungi codice al di alto profilo.

  2. Avvia il server di sviluppo locale, come descritto in Eseguire e testare i backend API localmente.

  3. Nel progetto client di Android Studio, individua il codice che riceve al servizio API backend. In genere, questo codice utilizza un Builder per configurare la richiesta API.

  4. Sostituisci l'URL principale nell'oggetto Builder (questo è l'URL a cui si connette il client Android nella chiamata all'API di backend) aggiungendo la riga:

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

    Ad esempio:

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

    Sostituisci YOUR_MACHINE_IP_ADDRESS con l'indirizzo IP del tuo sistema.

  5. Ricrea il progetto client Android.

  6. Se vuoi eseguire l'app client su un emulatore AVD:

    1. In Android Studio, vai a Strumenti > Android > Gestore AVD e avvia un AVD esistente, se ne hai uno, altrimenti creane uno e avvialo.
    2. Vai a Esegui > Esegui il debug di YOUR_PROJECT_NAME dove YOUR_PROJECT_NAME rappresenta il nome del tuo progetto Google Cloud.
    3. Quando ti viene chiesto di scegliere un dispositivo, seleziona la durata di visualizzazione media.
    4. Testa il client.
  7. Se vuoi eseguire l'app client su un dispositivo Android fisico:

    1. Assicurati che il tuo dispositivo Android sia abilitato per il debug.
    2. In Android Studio, vai a Esegui > Debug YOUR_PROJECT_NAME.
    3. Quando ti viene chiesto di scegliere un dispositivo, seleziona il tuo dispositivo Android fisico.
    4. Testa il client.

Codice sorgente del client di esempio

Per codice campione, consulta Esempio di Android Cloud Endpoints v2.0.