透過 GoogleApiClient 存取 Google API (已淘汰)

您可以使用 GoogleApiClient (「Google API 用戶端」) 這個物件來存取 Google Play 服務程式庫所提供的 Google API (例如 Google 登入、遊戲和雲端硬碟)。Google API 用戶端提供了 Google Play 服務常見的進入點,以及管理網路 使用者裝置和每個 Google 服務之間的連線。

不過,新版 GoogleApi 介面及其實作方式較簡單 也就是我們建議用於存取 Play 服務 API 的方式。 請參閱「存取 Google API」。

本指南說明如何:

  • 自動管理 Google Play 服務連線。
  • 對任何 Google Play 服務執行同步和非同步 API 呼叫。
  • 遇到這類罕見情況時,手動管理 Google Play 服務連線 無從得知詳情請參閱手動管理的連線
,瞭解如何調查及移除這項存取權。
圖 1:說明 Google API 用戶端如何提供 連結及呼叫任何可用的 Google Play 服務,例如: Google Play 遊戲和 Google 雲端硬碟。

必須先安裝 Google Play 服務程式庫 (修訂版本 15 以上版本) 。如果您還沒有這樣做,請按照 設定 Google Play 服務 SDK

啟動自動代管連線

您的專案連結至 Google Play 服務程式庫後,請建立 GoogleApiClient 使用 GoogleApiClient.Builder 您活動的 onCreate() 方法。 GoogleApiClient.Builder敬上 類別提供方法,讓您指定要使用的 Google API 和想要的 OAuth 2.0 範圍。以下程式碼範例可將 與 Google 雲端硬碟服務連線的 GoogleApiClient 執行個體:

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

您可以將多個 API 和多個範圍 GoogleApiClient敬上 只要在 addApi()addScope()

重要事項:如果您要將 Wearable API 與其他 API 一起新增至 GoogleApiClient,測試版本的裝置可能會發生用戶端連線錯誤 未安裝 Wear OS 應用程式。目的地: 如要避免連線錯誤,請呼叫 addApiIfAvailable() 方法並傳入 Wearable API,以便用戶端妥善處理缺少的 也能使用 Google Cloud CLI 或 Compute Engine API詳情請參閱「存取 Wearable API」。

如要啟動自動代管連線,您必須指定 OnConnectionFailedListener 的實作 介面接收無法解決的連線錯誤。自動管理 GoogleApiClient 執行個體會嘗試連線至 Google API 顯示 UI,嘗試修正任何可解析的連線失敗問題 (例如 Google Play 服務需要更新)。如果發生的無法 您將會接到: onConnectionFailed()

如果應用程式需要知道ConnectionCallbacks 會建立或暫停自動代管連線舉例來說,如果 應用程式會呼叫將資料寫入 Google API,因此您應該叫用這些呼叫 只有在呼叫 onConnected() 方法之後。

以下是實作回呼介面的活動範例,並新增 並上傳至 Google API 用戶端:

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

        // ...
    }
}

您的 GoogleApiClient 執行個體會在活動結束後自動連線 會呼叫 onStart(),並在呼叫 onStop() 後中斷連線。 您的應用程式可以立即開始 建構 GoogleApiClient 後傳送至 Google API 的讀取要求, 等待連線完成。

與 Google 服務通訊

連線之後,您的用戶端就能使用 您新增到 Google Cloud 控制台的 API 和範圍 GoogleApiClient 執行個體。

注意:撥號至特定 Google 服務前,您必須先註冊 開始開發應用程式如需相關操作說明,請參閱 這份入門指南,例如 Google 雲端硬碟Google 登入

使用 GoogleApiClient 執行讀取或寫入要求時,API 用戶端會傳回代表要求的 PendingResult 物件。 該要求會立即發生,在要求傳送至應用程式呼叫的 Google 服務之前。

舉例來說,以下要求從 Google 雲端硬碟讀取一個檔案 PendingResult 物件:

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

在應用程式建立 PendingResult 物件後, 您的應用程式可以指定要求要處理為非同步呼叫或同步呼叫。

提示:應用程式可在未連結 Google Play 服務時,將讀取要求排入佇列。適用對象 舉例來說,無論 GoogleApiClient 執行個體是否已連線,應用程式都可以呼叫方法,從 Google 雲端硬碟讀取檔案。建立連線後,系統就會將讀取要求排入佇列。如果您的應用程式呼叫了,則寫入要求會產生錯誤 Google API 用戶端未連線時,Google Play 服務寫入方法。

使用非同步呼叫

如要設定非同步要求,請呼叫 setResultCallback()敬上 導入 PendingResult,並提供 導入 ResultCallback 介面。適用對象 以下為非同步執行的要求:

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

在應用程式收到 Result 物件時 onResult() 回呼, 它會以您使用的 API 指定之適當子類別的執行個體提供 例如 DriveApi.MetadataBufferResult

使用同步呼叫

如果您希望程式碼按明確定義的順序執行,或許是因為 呼叫做為另一個引數,您可以呼叫 await() - PendingResult。這個動作會封鎖執行緒 並在載入非結構化資料時傳回 Result 物件 要求執行完畢。這個物件會由 假如您使用的 API DriveApi.MetadataBufferResult

因為呼叫 await() 會阻止執行緒,直到結果收到為止,您的應用程式一律不得向 使用者介面執行緒。應用程式可以透過 AsyncTask 物件建立新的執行緒,然後使用該執行緒發出同步要求。

以下範例顯示如何以同步呼叫向 Google 雲端硬碟提出檔案要求:

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

存取 Wearable API

Wearable API 為在手持裝置和穿戴式裝置上執行的應用程式提供通訊管道。 API 包含一組資料物件,可供系統傳送和同步處理 可透過資料層將重要事件通知應用程式。 Wearable API 適用於搭載 Android 4.3 (API 級別 18) 以上版本的裝置, 穿戴式裝置連線且 Wear OS 隨附應用程式 已安裝在裝置上。

單獨使用 Wearable API

如果您的應用程式使用 Wearable API,但不使用其他 Google API,您可以按照下列步驟新增這個 API: 呼叫 addApi() 方法。以下範例說明如何新增 將 Wearable API 套用至 GoogleApiClient 執行個體:

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

在無法使用 Wearable API 的情況下,連線要求會 包含 Wearable API 失敗,並傳回 API_UNAVAILABLE 錯誤代碼。

以下範例說明如何判斷是否提供 Wearable API

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

將 Wearable API 與其他 Google API 搭配使用

如果您的應用程式除了其他 Google API 也使用 Wearable API,請呼叫 addApiIfAvailable() 方法,並傳入 Wearable API,檢查該 API 是否可用。這項檢查可協助應用程式妥善處理 API 無法使用的情況。

以下範例說明如何存取 Wearable API,以及 Drive API

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

在上述範例中,GoogleApiClient 可以成功連線 Google 雲端硬碟無法使用,因此無法連線至 Wearable API。更新後 你連結了 GoogleApiClient 例如,在發出 API 呼叫之前,請確認 Wearable API 可用:

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

忽略 API 連線失敗

如果你呼叫 addApi(),但 GoogleApiClient 無法 成功連線至該 API,那麼該用戶端的完整連線作業都會失敗, 會觸發 onConnectionFailed() 回呼。

您可以使用 addApiIfAvailable()。如果使用 發生無法復原的錯誤,因此無法連線 addApiIfAvailable() (例如 Wear 的 API_UNAVAILABLE)、 該 API 就會從 GoogleApiClient 中捨棄,用戶端則會繼續 連線至其他 API。不過,如果 API 連線失敗並顯示可復原的錯誤 (例如 OAuth 同意聲明解析意圖),用戶端連線作業失敗。時間 使用的是自動管理的連線,GoogleApiClient 會嘗試 盡可能解決這類錯誤。使用手動管理連線時 包含解析意圖的 ConnectionResult 傳送至 onConnectionFailed() 回呼。API (應用程式介面) 只有在沒有故障的解決方法時,系統才會忽略連線失敗。 並新增 API 使用 addApiIfAvailable()。 瞭解如何實作手動連線失敗 處理,請參閱「處理連線失敗」。

由於 API 新增的 連線中可能不會一律顯示「addApiIfAvailable()GoogleApiClient 執行個體,您應新增檢查來保護對這些 API 的呼叫 使用 hasConnectedApi()。若要瞭解 您成功與用戶端的連線作業成功時, getConnectionResult() 並取得 ConnectionResult 物件。如果您的用戶端在未啟用的情況下呼叫 API 則呼叫會失敗,並顯示 API_NOT_AVAILABLE敬上 狀態碼。

如要透過 addApiIfAvailable() 新增的 API 需要 請將這些範圍新增為參數 addApiIfAvailable() 方法呼叫,而非使用 addScope() 方法。如果 API,系統可能無法要求以這種方法新增的範圍 連線失敗,無法取得 OAuth 同意,但透過 一律要求 addScope()

手動管理的連線

本指南的重點說明 使用 enableAutoManage 方法啟動 並自動解決錯誤。幾乎 在所有情況下,這是連線至 Google API 最簡單也最簡單的方式。 Android 應用程式。不過,在某些情況下您最好使用 應用程式中手動管理的 Google API 連線:

  • 在活動外存取 Google API,或保有 API 控制權 連線
  • 如何自訂連線錯誤處理和解析度

本節提供這類用途和其他進階用途的範例。

啟動手動管理的連線

如要手動管理連至 GoogleApiClient 的連線,您必須 指定回呼介面的實作。 ConnectionCallbacksOnConnectionFailedListener。 這些介面會收到回呼,以回應非同步 connect() 方法傳送 與 Google Play 服務的連線成功、失敗或遭到停權。

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

手動管理連線時,您必須呼叫 connect()敬上 和 disconnect() 方法。在活動中 情境最佳做法,是在活動的 onStart() 中呼叫 connect() 方法和disconnect(),使用活動的 onStop()方法。 connect()disconnect() 個方法 在使用自動代管連線時會自動呼叫。

如果您使用 GoogleApiClient 連線至需要 Google 雲端硬碟或 Google Play 遊戲等網站驗證時 首次連線嘗試將失敗,應用程式會收到一通來電 到 onConnectionFailed() 使用 SIGN_IN_REQUIRED 錯誤。

處理連線失敗問題

應用程式收到對 onConnectionFailed() 的呼叫時 回呼,應呼叫 hasResolution() 透過提供的 ConnectionResult 物件。如果傳回 true,應用程式可藉由以下方式,要求使用者立即採取行動以解決錯誤: 呼叫 startResolutionForResult()ConnectionResult 物件上。 startResolutionForResult() 方法 在這種情況下,行為與 startActivityForResult() 相同。 並啟動與情境相關的活動,協助使用者解決錯誤 (例如可協助使用者解決錯誤的活動) 選取帳戶)。

如果hasResolution() 傳回 false,應用程式應呼叫 GoogleApiAvailability.getErrorDialog()、 傳送錯誤代碼到這個方法這會傳回 Dialog (由 Google Play 提供) 顯示該錯誤的相關服務。對話方塊可能會單純提供說明訊息 或者也可能提供啟動活動以解決錯誤 (例如使用者需要安裝新版 Google Play 服務時)。

舉例來說, onConnectionFailed() 回呼方法現在應如下所示:

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

使用者完成 startResolutionForResult()敬上 或關閉 GoogleApiAvailability.getErrorDialog() 傳送的訊息。 您的活動會收到 onActivityResult() 回呼 RESULT_OK結果代碼。 這樣一來,您的應用程式就能呼叫 再次connect()。 例如:

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

在上述程式碼中,您可能會注意到布林值 mResolvingError。這會追蹤 使用者解決錯誤時的應用程式狀態,避免反覆嘗試 錯誤。例如,系統顯示帳戶挑選器對話方塊,可協助使用者解決 SIGN_IN_REQUIRED敬上 錯誤訊息,使用者可以旋轉畫面。這麼做會重新建立活動,並造成 onStart() 方法 然後呼叫 connect()。這個 就會產生另一次呼叫 startResolutionForResult()、 系統會在現有帳戶前方建立另一個帳戶挑選器對話方塊。

這個布林值只有在各個活動例項中持續時,才會維持其預期用途。 下一節將說明如何在使用其他使用者操作的情況下,維持應用程式的錯誤處理狀態 或裝置上發生的事件

修正錯誤時保留狀態

如何避免在 onConnectionFailed()敬上 先前嘗試解決錯誤時,您仍須保留布林值 會追蹤應用程式是否已經嘗試解決錯誤。

如以上程式碼範例所示,應用程式每次呼叫時,都應將布林值設為 true startResolutionForResult() 或是顯示 GoogleApiAvailability.getErrorDialog()。 然後,當您的應用程式收到 RESULT_OK 位於 onActivityResult() 回呼,將布林值設為 false

如要在活動重新啟動時追蹤布林值 (例如使用者旋轉螢幕), 使用 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);
}

接著在 30 秒內復原已儲存的狀態 onCreate():

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

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

您現在可以安全地執行應用程式,並手動連線至 Google Play 服務。