您可以使用 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 服務連線 無從得知詳情請參閱手動管理的連線。
必須先安裝 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
的連線,您必須
指定回呼介面的實作。
ConnectionCallbacks
和 OnConnectionFailedListener
。
這些介面會收到回呼,以回應非同步
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 服務。