從 Android 用戶端呼叫後端 API

此頁面說明 Android 用戶端如何呼叫使用於 App Engine 的 Cloud Endpoints Frameworks 建構的後端 API。

產生用戶端程式庫

您的 Android 用戶端需要從用戶端所使用的後端 API 生成的用戶端程式庫。若您還沒有用戶端程式庫,請參閱產生用戶端程式庫瞭解詳情。本文件提供以下步驟,說明如何將用戶端程式庫新增至 Android 用戶端專案。

設定專案

在這些操作說明中,您必須使用 Android Studio。 如果您目前沒有使用 Android Studio,則必須設定 Android Studio,以支援使用該架構的用戶端。

設定專案

在 Android Studio 中,您的專案使用 build.gradle 檔做為依附元件和其他設定。在預設情況下,Android Studio 會建立一個父項的專案層級 build.gradle 檔案,以及 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 中,但即使在舊版本中也是最佳做法)。如要執行上述作業,請使用 ThreadAsyncTask。例如:

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 用戶端正在呼叫需要驗證的端點,您必須:

  • 設定您的 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");

其中呼叫的第二個參數的前置字串為 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. 請記下執行本地開發伺服器的機器的 IP 位址,原因是當您增加程式碼至 Android 用戶端時將會需要此位址。

  2. 啟動本地開發伺服器,如在本地端執行與測試 API 後端所述。

  3. 在您的 Android Studio 用戶端專案中,找出操控後端 API 服務的程式碼。一般來說,這段程式碼會使用 Builder 來設定 API 要求。

  4. 以下內容覆寫 Builder 物件上的根網址 (這是 Android 用戶端在後端 API 呼叫中連接的網址):

    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 (如果有的話),或者建立新的 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] (偵錯 YOUR_PROJECT_NAME)
    3. 系統提示您選擇裝置時,請選取您的實體 Android 裝置。
    4. 測試您的用戶端。

範例用戶端原始碼

有關範例程式碼,請參閱 Android Cloud Endpoints v2.0 範例