Anda dapat menggunakan objek GoogleApiClient
("Klien Google API")
untuk mengakses Google API yang disediakan di library layanan Google Play
(seperti Login dengan Google, Game, dan Drive). Klien Google API menyediakan
titik entri umum ke layanan Google Play dan mengelola koneksi
jaringan antara perangkat pengguna dan setiap layanan Google.
Namun, antarmuka GoogleApi
yang lebih baru dan implementasinya lebih mudah
digunakan dan merupakan cara yang lebih disukai untuk mengakses API layanan Play.
Lihat Mengakses Google API.
Panduan ini menunjukkan cara:
- Mengelola koneksi Anda ke layanan Google Play secara otomatis.
- Melakukan panggilan API sinkron dan asinkron ke layanan Google Play mana pun.
- Mengelola koneksi Anda ke layanan Google Play secara manual dalam kasus yang jarang terjadi jika diperlukan. Untuk mempelajari lebih lanjut, lihat Koneksi yang dikelola secara manual.
Untuk memulai, Anda harus menginstal library layanan Google Play (revisi 15 atau yang lebih tinggi) untuk Android SDK terlebih dahulu. Jika Anda belum melakukannya, ikuti petunjuk di Menyiapkan SDK Layanan Google Play.
Memulai koneksi yang dikelola secara otomatis
Setelah project Anda ditautkan ke library layanan Google Play, buat instance
GoogleApiClient
menggunakan
GoogleApiClient.Builder
API dalam metode
onCreate()
aktivitas Anda. Class
GoogleApiClient.Builder
menyediakan metode yang memungkinkan Anda menentukan Google API yang ingin digunakan dan cakupan
OAuth 2.0 yang diinginkan. Berikut adalah contoh kode yang membuat
instance GoogleApiClient
yang terhubung dengan layanan Google Drive:
GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this) .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */) .addApi(Drive.API) .addScope(Drive.SCOPE_FILE) .build();
Anda dapat menambahkan beberapa API dan beberapa cakupan ke GoogleApiClient
yang sama dengan menambahkan panggilan tambahan ke addApi()
dan addScope()
.
Penting: Jika menambahkan Wearable
API bersama dengan API lain ke
GoogleApiClient
, Anda mungkin mengalami error koneksi klien di perangkat yang
tidak menginstal aplikasi Wear OS. Untuk menghindari error koneksi, panggil metode addApiIfAvailable()
dan teruskan Wearable
API agar klien Anda dapat menangani API yang hilang dengan baik. Untuk informasi selengkapnya, lihat Mengakses Wearable API.
Untuk memulai koneksi yang dikelola secara otomatis, Anda harus menentukan
penerapan untuk antarmuka
OnConnectionFailedListener
agar menerima error koneksi yang tidak dapat diselesaikan. Saat instance
GoogleApiClient
yang dikelola otomatis mencoba terhubung ke Google API, instance tersebut akan otomatis
menampilkan UI untuk mencoba memperbaiki kegagalan koneksi yang dapat di-resolve (misalnya, jika
layanan Google Play perlu diupdate). Jika terjadi error yang tidak dapat
diselesaikan, Anda akan menerima panggilan ke
onConnectionFailed()
.
Anda juga dapat menentukan implementasi opsional untuk antarmuka ConnectionCallbacks
jika aplikasi Anda perlu mengetahui kapan
koneksi yang dikelola secara otomatis dibuat atau ditangguhkan. Misalnya, jika
aplikasi Anda melakukan panggilan untuk menulis data ke Google API, panggilan ini hanya boleh dipanggil
setelah metode onConnected()
dipanggil.
Berikut adalah contoh aktivitas yang mengimplementasikan antarmuka callback dan menambahkannya ke Klien 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 // ... } }
Instance GoogleApiClient
akan otomatis terhubung setelah aktivitas Anda
memanggil onStart()
dan memutuskan hubungan setelah memanggil onStop()
.
Aplikasi Anda dapat langsung mulai membuat
permintaan baca ke Google API setelah mem-build GoogleApiClient
, tanpa
menunggu koneksi selesai.
Berkomunikasi dengan Layanan Google
Setelah terhubung, klien Anda dapat melakukan panggilan baca dan tulis menggunakan API khusus layanan yang
diberi otorisasi oleh aplikasi Anda, seperti yang ditentukan oleh API dan cakupan yang Anda tambahkan ke
instance GoogleApiClient
.
Catatan: Sebelum melakukan panggilan ke layanan Google tertentu, Anda mungkin perlu mendaftarkan aplikasi terlebih dahulu di Konsol Google Play. Untuk mendapatkan petunjuk, lihat panduan memulai yang sesuai untuk API yang Anda gunakan, seperti Google Drive atau Login dengan Google.
Saat Anda melakukan permintaan baca atau tulis menggunakan GoogleApiClient
, klien API akan menampilkan objek PendingResult
yang mewakili permintaan tersebut.
Hal ini terjadi segera, sebelum permintaan dikirim ke layanan Google yang dipanggil aplikasi Anda.
Misalnya, berikut adalah permintaan untuk membaca file dari Google Drive yang menyediakan objek PendingResult
:
Query query = new Query.Builder() .addFilter(Filters.eq(SearchableField.TITLE, filename)); PendingResult<DriveApi.MetadataBufferResult> result = Drive.DriveApi.query(mGoogleApiClient, query);
Setelah aplikasi memiliki objek PendingResult
,
aplikasi Anda dapat menentukan apakah permintaan ditangani sebagai panggilan asinkron atau sebagai panggilan sinkron.
Tips: Aplikasi Anda dapat mengantrekan permintaan baca saat tidak terhubung ke layanan Google Play. Misalnya,
aplikasi Anda dapat memanggil metode untuk membaca file dari Google Drive, terlepas dari apakah instance GoogleApiClient
Anda sudah terhubung atau belum. Setelah koneksi dibuat, permintaan baca yang diantrekan akan dieksekusi. Permintaan tulis akan menghasilkan error jika aplikasi Anda memanggil
metode tulis layanan Google Play saat Klien Google API tidak terhubung.
Menggunakan panggilan asinkron
Untuk membuat permintaan asinkron, panggil
setResultCallback()
di PendingResult
dan berikan
implementasi antarmuka
ResultCallback
. Misalnya, berikut permintaan yang dijalankan secara asinkron:
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. // ... } }); }
Saat aplikasi Anda menerima objek Result
dalam
callback onResult()
,
objek tersebut dikirim sebagai instance subclass yang sesuai seperti yang ditentukan oleh API yang Anda gunakan,
seperti
DriveApi.MetadataBufferResult
.
Menggunakan panggilan sinkron
Jika Anda ingin kode dieksekusi dalam urutan yang ditentukan secara ketat, mungkin karena hasil dari satu
panggilan diperlukan sebagai argumen untuk panggilan lainnya, Anda dapat membuat permintaan sinkron dengan memanggil
await()
di
PendingResult
. Tindakan ini akan memblokir thread
dan menampilkan objek Result
saat
permintaan selesai. Objek ini dikirim sebagai instance subclass yang sesuai seperti yang ditentukan oleh
API yang Anda gunakan, misalnya
DriveApi.MetadataBufferResult
.
Karena memanggil await()
memblokir thread hingga hasilnya tiba, aplikasi Anda tidak boleh membuat permintaan sinkron ke Google API di
UI thread. Aplikasi Anda dapat membuat thread baru menggunakan objek AsyncTask
, dan menggunakan thread tersebut untuk membuat permintaan sinkron.
Contoh berikut menunjukkan cara membuat permintaan file ke Google Drive sebagai panggilan sinkron:
private void loadFile(String filename) { new GetFileTask().execute(filename); } private class GetFileTask extends AsyncTask<String, Void, Void> { 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 // ... } }
Mengakses Wearable API
Wearable API menyediakan saluran komunikasi untuk aplikasi yang berjalan di perangkat genggam dan wearable. API ini terdiri dari sekumpulan objek data yang dapat dikirim dan disinkronkan oleh sistem, serta pemroses yang memberi tahu aplikasi Anda tentang peristiwa penting menggunakan lapisan data. Wearable API tersedia di perangkat yang menjalankan Android 4.3 (API level 18) atau yang lebih tinggi saat perangkat wearable terhubung dan aplikasi pendamping Wear OS diinstal di perangkat.
Menggunakan Wearable API mandiri
Jika aplikasi Anda menggunakan Wearable API, tetapi tidak menggunakan Google API lainnya, Anda dapat menambahkan API ini dengan
memanggil metode addApi()
. Contoh berikut menunjukkan cara menambahkan
Wearable API ke instance GoogleApiClient
:
GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this) .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */) .addApi(Wearable.API) .build();
Jika Wearable API tidak tersedia, permintaan koneksi yang
menyertakan Wearable API akan gagal dengan
kode error
API_UNAVAILABLE
.
Contoh berikut menunjukkan cara menentukan apakah Wearable API tersedia:
// 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 } // ... }
Menggunakan Wearable API dengan Google API lainnya
Jika aplikasi Anda menggunakan Wearable API selain Google API lainnya, panggil
metode addApiIfAvailable()
dan teruskan Wearable API untuk memeriksa apakah API tersebut tersedia. Anda dapat menggunakan pemeriksaan ini untuk membantu aplikasi menangani kasus saat API tidak tersedia dengan baik.
Contoh berikut menunjukkan cara mengakses Wearable API beserta 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();
Pada contoh di atas, GoogleApiClient
berhasil terhubung dengan
Google Drive tanpa terhubung ke Wearable API jika tidak tersedia. Setelah
menghubungkan instance GoogleApiClient
, pastikan Wearable API tersedia sebelum melakukan panggilan API:
boolean wearAvailable = mGoogleApiClient.hasConnectedApi(Wearable.API);
Mengabaikan Kegagalan Koneksi API
Jika Anda memanggil addApi()
dan GoogleApiClient
tidak dapat
terhubung dengan API tersebut, seluruh operasi koneksi untuk klien tersebut akan gagal dan
memicu callback onConnectionFailed()
.
Anda dapat mendaftarkan kegagalan koneksi API untuk diabaikan menggunakan
addApiIfAvailable()
. Jika API yang ditambahkan dengan
addApiIfAvailable()
gagal terhubung karena error yang tidak dapat dipulihkan
(seperti API_UNAVAILABLE
untuk Wear),
API tersebut akan dihapus dari GoogleApiClient
dan klien akan melanjutkan untuk
terhubung ke API lain. Namun, jika koneksi API gagal dengan error yang dapat dipulihkan (seperti
intent resolusi izin OAuth), operasi koneksi klien akan gagal. Saat
menggunakan koneksi yang dikelola secara otomatis, GoogleApiClient
akan mencoba
menyelesaikan error tersebut jika memungkinkan. Saat menggunakan koneksi yang dikelola secara manual,
ConnectionResult
yang berisi intent resolusi
akan dikirim ke callback onConnectionFailed()
. Kegagalan koneksi API hanya diabaikan jika tidak ada resolusi untuk kegagalan tersebut dan API ditambahkan dengan addApiIfAvailable()
.
Untuk mempelajari cara menerapkan penanganan kegagalan koneksi
manual, lihat Menangani kegagalan koneksi.
Karena API yang ditambahkan dengan
addApiIfAvailable()
mungkin tidak selalu ada di instance
GoogleApiClient
yang terhubung, Anda harus menjaga panggilan ke API ini dengan menambahkan pemeriksaan
menggunakan hasConnectedApi()
. Untuk mengetahui alasan
API tertentu gagal terhubung saat seluruh operasi koneksi berhasil untuk klien, panggil
getConnectionResult()
dan dapatkan kode error dari
objek ConnectionResult
. Jika klien Anda memanggil API saat tidak
terhubung ke klien, panggilan akan gagal dengan
kode status
API_NOT_AVAILABLE
.
Jika API yang Anda tambahkan melalui addApiIfAvailable()
memerlukan satu atau
beberapa cakupan, tambahkan cakupan tersebut sebagai parameter dalam
panggilan metode addApiIfAvailable()
, bukan dengan menggunakan
metode addScope()
. Cakupan yang ditambahkan menggunakan pendekatan ini mungkin tidak diminta jika koneksi API gagal sebelum mendapatkan izin OAuth, sedangkan cakupan yang ditambahkan dengan addScope()
selalu diminta.
Koneksi yang dikelola secara manual
Sebagian besar panduan ini menunjukkan cara menggunakan metode enableAutoManage
untuk memulai koneksi yang dikelola secara otomatis dengan error yang di-resolve secara otomatis. Dalam hampir
semua kasus, ini adalah cara terbaik dan termudah untuk terhubung ke Google API dari
aplikasi Android Anda. Namun, ada beberapa situasi saat Anda ingin menggunakan
koneksi yang dikelola secara manual ke Google API di aplikasi Anda:
- Untuk mengakses Google API di luar aktivitas atau mempertahankan kontrol koneksi API
- Untuk menyesuaikan penanganan dan penyelesaian error koneksi
Bagian ini memberikan contoh kasus penggunaan lanjutan ini dan lainnya.
Memulai koneksi yang dikelola secara manual
Untuk memulai koneksi yang dikelola secara manual ke GoogleApiClient
, Anda harus
menentukan implementasi untuk antarmuka callback,
ConnectionCallbacks
dan OnConnectionFailedListener
.
Antarmuka ini menerima callback sebagai respons terhadap metode
connect()
asinkron saat
koneksi ke layanan Google Play berhasil, gagal, atau ditangguhkan.
mGoogleApiClient = new GoogleApiClient.Builder(this) .addApi(Drive.API) .addScope(Drive.SCOPE_FILE) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build()
Saat mengelola koneksi secara manual, Anda harus memanggil metode
connect()
dan
disconnect()
pada titik yang tepat dalam siklus proses aplikasi. Dalam konteks
aktivitas, praktik terbaiknya adalah memanggil connect()
dalam metode onStart()
aktivitas dan disconnect()
dalam metode onStop()
aktivitas.
Metode connect()
dan
disconnect()
dipanggil secara otomatis saat menggunakan koneksi yang dikelola secara otomatis.
Jika Anda menggunakan GoogleApiClient
untuk terhubung ke API yang memerlukan
autentikasi, seperti Google Drive atau Google Play Game, kemungkinan besar
upaya koneksi pertama Anda akan gagal dan aplikasi Anda akan menerima panggilan
ke onConnectionFailed()
dengan error SIGN_IN_REQUIRED
karena akun pengguna tidak ditentukan.
Menangani kegagalan koneksi
Saat aplikasi menerima panggilan ke callback onConnectionFailed()
, Anda harus memanggil hasResolution()
pada objek ConnectionResult
yang disediakan. Jika menampilkan true, aplikasi Anda dapat meminta pengguna untuk segera mengambil tindakan guna menyelesaikan error dengan
memanggil startResolutionForResult()
pada objek ConnectionResult
.
Metode startResolutionForResult()
berperilaku sama seperti startActivityForResult()
dalam situasi ini,
dan meluncurkan aktivitas yang sesuai dengan konteks yang membantu pengguna menyelesaikan error (seperti aktivitas yang membantu pengguna
memilih akun).
Jika hasResolution()
menampilkan nilai salah (false), aplikasi Anda harus memanggil
GoogleApiAvailability.getErrorDialog()
,
yang meneruskan kode error ke metode ini. Tindakan ini akan menampilkan
Dialog
yang disediakan oleh layanan
Google Play yang sesuai dengan error. Dialog mungkin hanya memberikan pesan yang menjelaskan
error, atau juga dapat memberikan tindakan untuk meluncurkan aktivitas yang dapat menyelesaikan error
(seperti saat pengguna perlu menginstal layanan Google Play versi yang lebih baru).
Misalnya, metode callback
onConnectionFailed()
Anda sekarang akan terlihat seperti ini:
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(); } } }
Setelah pengguna menyelesaikan dialog yang disediakan oleh
startResolutionForResult()
atau menutup pesan yang disediakan oleh GoogleApiAvailability.getErrorDialog()
,
aktivitas Anda akan menerima callback
onActivityResult()
dengan kode hasil
RESULT_OK
.
Kemudian, aplikasi Anda dapat memanggil
connect()
lagi.
Contoh:
@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(); } } } }
Dalam kode di atas, Anda mungkin melihat boolean, mResolvingError
. Hal ini melacak
status aplikasi saat pengguna menyelesaikan error untuk menghindari upaya berulang dalam menyelesaikan error
yang sama. Misalnya, saat dialog pemilih akun ditampilkan untuk membantu pengguna mengatasi error
SIGN_IN_REQUIRED
, pengguna dapat memutar layar. Tindakan ini akan membuat ulang aktivitas Anda dan menyebabkan
metode onStart()
dipanggil lagi, yang kemudian memanggil
connect()
lagi. Hal ini
menghasilkan panggilan lain ke
startResolutionForResult()
,
yang membuat dialog pemilih akun lain di depan dialog yang ada.
Boolean ini berfungsi sesuai tujuannya hanya jika tetap ada di seluruh instance aktivitas. Bagian berikutnya menjelaskan cara mempertahankan status penanganan error aplikasi Anda meskipun ada tindakan atau peristiwa pengguna lain yang terjadi di perangkat.
Mempertahankan status saat menyelesaikan error
Untuk menghindari eksekusi kode di
onConnectionFailed()
saat upaya sebelumnya untuk mengatasi error sedang berlangsung, Anda harus mempertahankan boolean yang
melacak apakah aplikasi Anda sudah mencoba mengatasi error.
Seperti yang ditunjukkan dalam contoh kode di atas, aplikasi Anda harus menetapkan boolean ke true
setiap kali memanggil
startResolutionForResult()
atau menampilkan dialog dari
GoogleApiAvailability.getErrorDialog()
.
Kemudian, saat aplikasi Anda menerima
RESULT_OK
dalam
callback
onActivityResult()
, tetapkan boolean ke false
.
Untuk melacak boolean di seluruh aktivitas yang dimulai ulang (seperti saat pengguna memutar layar),
simpan boolean dalam data instance tersimpan aktivitas menggunakan
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); }
Kemudian, pulihkan status yang disimpan selama
onCreate()
:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ... mResolvingError = savedInstanceState != null && savedInstanceState.getBoolean(STATE_RESOLVING_ERROR, false); }
Sekarang Anda siap menjalankan aplikasi dengan aman dan terhubung ke layanan Google Play secara manual.