Android クライアントからのバックエンド API の呼び出し

このページでは、App Engine 用に Cloud Endpoints Frameworks でビルドしたバックエンド API を Android クライアントから呼び出す方法について説明します。

クライアント ライブラリを生成する

Android クライアントはクライアントが使用しているバックエンド API から生成されたクライアント ライブラリを必要とします。現時点でクライアント ライブラリが存在しない場合は、クライアント ライブラリを生成するで詳細をご確認ください。このドキュメントで説明する手順は、Android クライアント プロジェクトにクライアント ライブラリを追加するためのものです。

プロジェクトのセットアップを行う

この手順では Android Studio を使用します。 まだ設定していない場合は、Android Studio を設定して、フレームワークを使用するクライアントをサポートするようにしてください。

プロジェクトの構成

Android Studio では、従属関係やその他の設定のために build.gradle ファイルをプロジェクトで使用します。デフォルトで、Android Studio は、親プロジェクト レベルの build.gradle ファイルと Android アプリ固有のファイルを Android モジュール内に作成します。下記の手順は Android モジュール内のアプリ固有の build.gradle に関する説明です。

build.gradle を構成するには、次の手順を実行します。

  1. build.gradle をダブルクリックして開きます。

  2. 開いたファイルを編集し下記の行を追加します。

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

    com.mycompany.myapp は、実際の値に置き換えてください。

  3. [File] > [Save All] の順にクリックして Android Studio を終了し再起動します。

プロジェクトへのクライアント ライブラリの追加

Android プロジェクトにクライアント ライブラリを追加するには:

  1. プロジェクトに /libs ディレクトリを追加します(まだ存在しない場合)。このディレクトリは /src ディレクトリと同じ階層にあります。

  2. バックエンド API から生成したクライアント ライブラリを /libs にコピーします。

  3. 追加したライブラリを選択して右クリックし、[Add As Library] を選択してプロジェクトに追加します。

サービス オブジェクトの作成

プロジェクト コードでは、バックエンド API にリクエストを送信するためサービス オブジェクトを使用する必要があります。未認証リクエストについては、次のようにサービス オブジェクトを作成してください。

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

BACKEND_API_NAME は実際のバックエンド API の名前に置き換えてください。

バックエンド API の呼び出し

プロジェクトでは、サービス オブジェクトを使用して API を呼び出してください。例:

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

このスニペットでは、サーバー上のすべての Score オブジェクトのリストをリクエストしています。list にパラメータまたはリクエストの本文が必要な場合は、呼び出しの際にそれを渡します。Android Studio は対応可能なメソッド呼び出しと必須のパラメータのコードを特定し、コードを完成させます。

API 呼び出しはネットワーク経由でリクエストされるため、スレッド内でリクエストを実行する必要があります(この必要条件は Android の最新バージョンに追加されましたが、古いバージョンのベスト プラクティスでもあります)。これを行うには、Thread または AsyncTask を使用します。例:

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

認証された呼び出しの実行

ここでは、クライアント コーディングで追加が必要となる手順のみを説明します。また、ユーザーの認証にある説明に沿って、すでに認証のための Endpoints Frameworks サポートが追加されていることを前提としています。

Android クライアントが Endpoint に対して認証を必要とする呼び出しを実行するには、次の条件を満たす必要があります。

  • サービス オブジェクトに認証情報を提供するように Android クライアントを構成する。
  • ログイン アカウントのユーザー選択をサポートするためにアカウント ピッカーを使用する。

以下で詳細について説明します。

認証情報を提供するための Android クライアントの構成

認証を必要とするバックエンド API へのリクエストをサポートするには、Android クライアントがユーザー認証情報を取得し、サービス オブジェクトに渡す必要があります。

ユーザー認証情報を取得し、アカウント ピッカーを使用するには、次の Android 権限が必要です。

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

ユーザー認証情報を取得するには、次のように GoogleAccountCredential.usingAudience を呼び出します。

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

ここで、呼び出しの 2 番目のパラメータには、server:client_id の後ろにバックエンド API のウェブ クライアント ID を付け加えて指定します。

サンプルコード: サービス オブジェクト用の認証情報の取得

認証情報を取得してサービス オブジェクトに引き渡すためのコードは次のとおりです。

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

上記のサンプルコードは Android アプリに保存されているすべての共有環境設定を検索し、ユーザーがアプリケーションへの認証に使おうとするアカウントの名前を検出しようとします。成功すれば、コードは認証情報オブジェクトを生成し、サービス オブジェクトに渡します。この認証情報によって、Android アプリからバックエンドに適切なトークンを渡すことが可能になります。

コードサンプルによって、Android アプリが使用すべきアカウントをすでに知っているかどうかが確認されます。認識している場合は論理フローが続行し、Android アプリを実行できます。どのアカウントを使用するかをアプリが認識していない場合、アプリはログイン画面を表示するか、ユーザーにアカウントの選択を促します

最後に、サンプルコードは、認証情報オブジェクトを生成して、それをサービス オブジェクトに渡します。この認証情報により、Android アプリは App Engine ウェブアプリに適切なトークンを渡すことができます。

アカウント ピッカーの使用

Android はユーザー アカウントを選択するためのインテントを提供します。呼び出し方法は次のとおりです。

static final int REQUEST_ACCOUNT_PICKER = 2;

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

このインテントの結果を解釈するためのハンドラが、ここに示されています。

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

ローカル開発用サーバーに対する Android クライアントのテスト

本番環境用 App Engine で稼働中のバックエンド API に対するクライアントのテストは、変更を加えることなくいつでも実行できます。しかし、ローカル開発用サーバーで稼働中のバックエンド API に対してクライアント テストを行う場合には、ローカル開発用サーバーを実行しているマシンの IP アドレスを参照するようクライアントのコードを変更しなければなりません。

ローカル開発用サーバーを使用して必要な変更とテストを実行するには、次の手順を実行します。

  1. Android クライアントにコードを追加する際に必要になるため、ローカル開発用サーバーを実行しているマシンの IP アドレスを書き留めます。

  2. ローカルで API をテストするの説明に沿ってローカル開発用サーバーを起動します。

  3. Android Studio クライアント プロジェクトで、バックエンド API サービスに対するハンドルを取得するコードを見つけます。通常、このコードは Builder を使用して API リクエストを設定します。

  4. 行を追加して Builder オブジェクトにルート URL(バックエンド API 呼び出しで Android クライアントが接続する URL)をオーバーライドします。

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

    例:

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

    YOUR_MACHINE_IP_ADDRESS の部分は、実際のシステムの IP アドレスに置き換えてください。

  5. Android クライアント プロジェクトを再ビルドします。

  6. クライアント アプリを AVD エミュレータで実行する場合、次の操作を行います。

    1. Android Studio で [Tools] > [Android] > [AVD Manager] を選択し、AVD がすでにある場合は起動します。AVD がない場合は作成して、それを起動します。
    2. [Run] > [Debug YOUR_PROJECT_NAME] を選択します。ここで、YOUR_PROJECT_NAME は Google Cloud プロジェクトの名前を表します。
    3. デバイスを選択するよう要求されたら、AVD を選択します。
    4. クライアントをテストします。
  7. クライアント アプリを Android 物理デバイスで実行する場合、次の操作を行います。

    1. 使用する Android デバイスでデバッグの有効化が設定されていることを確認してください。
    2. Android Studio で、[Run] > [Debug YOUR_PROJECT_NAME] を選択します。
    3. デバイスを選択するよう要求されたら、お使いの Android 物理デバイスを選択します。
    4. クライアントをテストします。

サンプル クライアント ソースコード

サンプルコードについては、Android Cloud Endpoints v2.0 の例をご覧ください。