Mengakses Google API dengan GoogleApiClient (tidak digunakan lagi)

Anda dapat menggunakan 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 jaringan koneksi antara perangkat pengguna dan setiap layanan Google.

Namun, antarmuka GoogleApi yang lebih baru dan implementasinya lebih mudah digunakan dan merupakan cara yang direkomendasikan 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 salah satu layanan Google Play.
  • Kelola koneksi Anda ke layanan Google Play secara manual dalam kasus yang jarang terjadi saat diperlukan. Untuk mempelajari lebih lanjut, lihat Koneksi yang dikelola secara manual.
Gambar 1: Ilustrasi yang menunjukkan cara Klien Google API menyediakan antarmuka untuk menghubungkan dan melakukan panggilan ke salah satu layanan Google Play yang tersedia seperti Google Play Game dan Google Drive.

Untuk memulai, Anda harus menginstal library layanan Google Play terlebih dahulu (revisi 15 atau yang lebih baru) untuk Android SDK. Jika Anda belum melakukannya, ikuti petunjuk di Menyiapkan SDK Layanan Google Play.

Memulai koneksi yang dikelola secara otomatis

Setelah project Anda ditautkan ke pustaka layanan Google Play, buat instance GoogleApiClient menggunakan GoogleApiClient.Builder dalam metode onCreate() . Tujuan GoogleApiClient.Builder menyediakan metode yang memungkinkan Anda untuk menetapkan Google API yang ingin Anda gunakan dan Cakupan OAuth 2.0. 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 bisa menambahkan beberapa API dan beberapa cakupan ke GoogleApiClient dengan menambahkan panggilan tambahan ke addApi() dan addScope().

Penting: Jika Anda menambahkan Wearable API bersama dengan API lain ke GoogleApiClient, Anda mungkin akan mengalami error koneksi klien pada perangkat yang belum menginstal aplikasi Wear OS. Kepada menghindari error koneksi, panggil metode addApiIfAvailable() dan teruskan Wearable API agar klien Anda dapat menangani data yang hilang Compute Engine API. Untuk mengetahui informasi selengkapnya, lihat Mengakses Wearable API.

Untuk memulai koneksi yang dikelola secara otomatis, Anda harus menentukan implementasi untuk OnConnectionFailedListener untuk menerima {i>error<i} koneksi yang tidak dapat diselesaikan. Jika layanan pengelolaan otomatis Instance GoogleApiClient mencoba terhubung ke Google API, instance akan otomatis menampilkan UI untuk mencoba memperbaiki kegagalan koneksi yang dapat diselesaikan (misalnya, Layanan Google Play perlu diupdate). Jika terjadi {i>error<i} yang tidak dapat diselesaikan, Anda akan menerima panggilan ke onConnectionFailed()

Anda juga dapat menentukan implementasi opsional untuk antarmuka ConnectionCallbacks jika aplikasi perlu mengetahui kapan koneksi terkelola secara otomatis dibuat atau ditangguhkan. Misalnya jika aplikasi Anda melakukan panggilan untuk menulis data ke Google API, perintah ini harus dipanggil hanya setelah metode onConnected() dipanggil.

Berikut adalah contoh aktivitas yang mengimplementasikan antarmuka callback dan menambahkan mereka 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 Anda akan otomatis terhubung setelah aktivitas Anda memanggil onStart() dan memutuskan sambungan setelah memanggil onStop(). Aplikasi Anda bisa segera mulai membuat permintaan baca ke Google API setelah membangun GoogleApiClient, tanpa menunggu koneksi selesai.

Berkomunikasi dengan Layanan Google

Setelah terhubung, klien Anda dapat melakukan panggilan baca dan tulis menggunakan API khusus layanan untuk yang diotorisasi aplikasi Anda, seperti yang ditetapkan oleh API dan cakupan yang Anda tambahkan Instance GoogleApiClient.

Catatan: Sebelum melakukan panggilan ke layanan Google tertentu, Anda mungkin perlu mendaftarkan aplikasi Anda di Google Developer Console. Untuk petunjuk, lihat panduan memulai 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 oleh aplikasi Anda.

Misalnya, berikut 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 Anda memiliki objek PendingResult, selanjutnya aplikasi Anda bisa 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. Sebagai misalnya, aplikasi Anda dapat memanggil metode untuk membaca file dari Google Drive, terlepas dari apakah instance GoogleApiClient Anda terhubung atau belum. Setelah koneksi dibuat, permintaan baca dalam antrean akan dieksekusi. Permintaan tulis akan menghasilkan error jika aplikasi Anda memanggil Layanan Google Play menulis metode saat Klien Google API Anda tidak terhubung.

Menggunakan panggilan asinkron

Untuk membuat permintaan asinkron, panggil setResultCallback() di PendingResult, lalu berikan penerapan Antarmuka ResultCallback. Sebagai berikut ini permintaan yang dieksekusi 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 di callback onResult(), dikirim sebagai instance dari subclass yang sesuai seperti yang ditetapkan oleh API yang Anda gunakan, seperti DriveApi.MetadataBufferResult.

Menggunakan panggilan sinkron

Jika Anda ingin kode Anda dieksekusi dalam urutan yang didefinisikan secara ketat, mungkin karena hasil dari satu diperlukan sebagai argumen bagi panggilan lain, Anda bisa membuat permintaan sinkron dengan memanggil await() di PendingResult. Ini memblokir thread dan menampilkan objek Result saat selesai. Objek ini dikirim sebagai instance subclass yang sesuai seperti yang ditetapkan oleh API yang Anda gunakan, misalnya DriveApi.MetadataBufferResult

Karena memanggil await() memblokir thread hingga hasil masuk, aplikasi Anda tidak boleh membuat permintaan sinkron ke Google API di Thread UI. 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 {
    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 pada perangkat genggam dan wearable. API terdiri dari serangkaian objek data yang dapat dikirim dan disinkronkan oleh sistem, dan pemroses yang memberi tahu aplikasi tentang peristiwa penting menggunakan lapisan data. Tujuan Wearable API tersedia di perangkat yang menjalankan Android 4.3 (API level 18) atau yang lebih tinggi jika perangkat wearable terhubung dan aplikasi pendamping Wear OS diinstal di perangkat.

Menggunakan Wearable API secara mandiri

Jika aplikasi Anda menggunakan Wearable API tetapi tidak Google API lainnya, Anda dapat menambahkan API ini dengan memanggil metode addApi(). Contoh berikut menunjukkan cara menambahkan Wearable API ke instance GoogleApiClient Anda:

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

Dalam situasi ketika Wearable API tidak tersedia, permintaan koneksi yang menyertakan Wearable API gagal dengan API_UNAVAILABLE pada kode error Anda.

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 bersama dengan Google API lainnya, panggil addApiIfAvailable() dan teruskan Wearable API untuk memeriksa ketersediaannya. Anda dapat menggunakan pemeriksaan ini untuk membantu aplikasi menangani kasus dengan baik ketika API tidak tersedia.

Contoh berikut menunjukkan cara mengakses Wearable API beserta API Drive:

// 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. Sesudah Anda menghubungkan GoogleApiClient pastikan bahwa 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 berhasil terhubung ke API tersebut, seluruh operasi koneksi untuk klien tersebut gagal dan memicu callback onConnectionFailed().

Anda dapat mendaftarkan kegagalan koneksi API agar diabaikan dengan menggunakan addApiIfAvailable() Jika API yang ditambahkan dengan addApiIfAvailable() gagal terhubung karena error yang tidak dapat dipulihkan (seperti API_UNAVAILABLE untuk Wear), API tersebut dihapus dari GoogleApiClient Anda dan klien melanjutkan ke menghubungkan ke API lain. Akan tetapi, jika koneksi API gagal dengan error yang dapat dipulihkan (seperti intent resolusi izin OAuth), operasi penyambungan klien akan gagal. Kapan menggunakan koneksi yang dikelola secara otomatis, GoogleApiClient akan mencoba untuk mengatasi kesalahan tersebut bila memungkinkan. Saat menggunakan koneksi yang dikelola secara manual ConnectionResult yang berisi intent resolusi dikirim ke callback onConnectionFailed(). API Kegagalan koneksi akan diabaikan hanya jika tidak ada resolusi untuk kegagalan tersebut dan API telah ditambahkan dengan addApiIfAvailable(). Untuk mempelajari cara mengimplementasikan kegagalan koneksi manual lihat Menangani kegagalan koneksi.

Karena API yang ditambahkan dengan addApiIfAvailable() mungkin tidak selalu ada dalam Instance GoogleApiClient, Anda harus menjaga panggilan ke API ini dengan menambahkan pemeriksaan menggunakan hasConnectedApi(). Untuk mengetahui mengapa API tertentu gagal terhubung ketika seluruh operasi koneksi klien berhasil, panggil getConnectionResult() dan dapatkan kode error dari Objek ConnectionResult. Jika klien Anda memanggil API padahal tidak terhubung ke klien, panggilan gagal dengan API_NOT_AVAILABLE kode status.

Jika API yang Anda tambahkan melalui addApiIfAvailable() memerlukan satu atau lebih banyak cakupan, tambahkan cakupan tersebut sebagai parameter dalam Panggilan metode addApiIfAvailable(), bukan menggunakan Metode addScope(). Cakupan yang ditambahkan menggunakan pendekatan ini mungkin tidak diminta jika API gagal sebelum mendapatkan persetujuan OAuth, sedangkan cakupan ditambahkan dengan addScope() selalu diminta.

Koneksi yang dikelola secara manual

Sebagian besar panduan ini menunjukkan cara menggunakan Metode enableAutoManage untuk memulai koneksi terkelola secara otomatis dengan error yang diselesaikan secara otomatis. Hampir dalam dalam semua kasus, ini adalah cara terbaik dan termudah untuk terhubung ke Google API dari aplikasi Android. Namun, ada beberapa situasi di mana Anda ingin menggunakan koneksi terkelola secara manual ke Google API di aplikasi Anda:

  • Untuk mengakses Google API di luar aktivitas atau mempertahankan kontrol API koneksi
  • Untuk menyesuaikan penanganan dan resolusi error koneksi

Bagian ini memberikan contoh hal tersebut dan kasus penggunaan lanjutan lainnya.

Memulai koneksi yang dikelola secara manual

Untuk memulai koneksi yang dikelola secara manual ke GoogleApiClient, Anda harus menetapkan implementasi untuk antarmuka callback, ConnectionCallbacks dan OnConnectionFailedListener. Antarmuka ini menerima callback untuk merespons model Metode connect() 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 connect() dan disconnect() di waktu yang tepat dalam siklus proses aplikasi Anda. Dalam aktivitas konteks, praktik terbaik adalah memanggil connect() dalam onStart() aktivitas Anda dan disconnect() dalam metode onStop() aktivitas Anda. Class connect() dan Metode 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, ada kemungkinan upaya koneksi pertama Anda akan gagal dan aplikasi Anda akan menerima panggilan ke onConnectionFailed() dengan SIGN_IN_REQUIRED karena akun pengguna tidak ditentukan.

Menangani kegagalan koneksi

Saat aplikasi menerima panggilan ke onConnectionFailed() Anda, Anda harus memanggil hasResolution() di ConnectionResult yang disediakan . Jika menampilkan nilai benar, aplikasi bisa meminta pengguna untuk segera mengambil tindakan untuk 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 mengatasi error (seperti aktivitas yang membantu pengguna pilih akun).

Jika hasResolution() menghasilkan nilai salah, aplikasi Anda harus memanggil GoogleApiAvailability.getErrorDialog(), meneruskan kode error ke metode ini. Ini akan mengembalikan Dialog disediakan oleh Google Play layanan yang sesuai dengan masalah tersebut. Dialog mungkin menampilkan pesan yang menjelaskan kesalahan, atau juga dapat memberikan tindakan untuk meluncurkan aktivitas yang dapat mengatasi kesalahan (seperti saat pengguna perlu menginstal versi layanan Google Play yang lebih baru).

Misalnya, Metode callback onConnectionFailed() 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 menerima onActivityResult() dengan callback RESULT_OK kode hasil. Aplikasi Anda kemudian 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 ketika pengguna menyelesaikan error untuk menghindari upaya berulang kali menyelesaikan {i>error<i}. Misalnya, saat dialog pemilih akun ditampilkan untuk membantu pengguna menyelesaikan SIGN_IN_REQUIRED , pengguna mungkin memutar layar. Ini akan membuat ulang aktivitas Anda dan menyebabkan Metode onStart() agar dipanggil lagi, yang kemudian memanggil connect() lagi. Ini menghasilkan panggilan lain ke startResolutionForResult(), yang membuat dialog pemilih akun lain di depan akun yang ada.

Boolean ini memenuhi tujuan yang dimaksudkan hanya jika tetap bertahan di seluruh instance aktivitas. Bagian berikutnya menjelaskan cara mempertahankan status penanganan error aplikasi Anda meskipun ada tindakan pengguna lain atau peristiwa yang terjadi di perangkat.

Mempertahankan status saat menyelesaikan error

Untuk menghindari eksekusi kode di onConnectionFailed() ketika upaya sebelumnya untuk menyelesaikan kesalahan sedang berlangsung, Anda perlu mempertahankan boolean yang melacak apakah aplikasi Anda sudah mencoba menyelesaikan error.

Seperti yang ditunjukkan pada contoh kode di atas, aplikasi Anda harus menetapkan boolean ke true setiap kali memanggil startResolutionForResult() atau menampilkan dialog dari GoogleApiAvailability.getErrorDialog(). Kemudian, ketika aplikasi Anda menerima RESULT_OK di onActivityResult() , setel boolean ke false.

Untuk melacak boolean di seluruh proses mulai ulang (seperti saat pengguna memutar layar), simpan Boolean dalam data instance aktivitas yang disimpan 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);
}

Kini Anda siap untuk menjalankan aplikasi dengan aman dan menghubungkan ke layanan Google Play secara manual.