GoogleApiClient
(„Klient interfejsu API Google”)
dostęp do interfejsów API Google udostępnianych w bibliotece Usług Google Play
(takich jak Logowanie przez Google, Gry czy Dysk). Klient interfejsów API Google zapewnia
wspólny punkt wejścia do Usług Google Play i zarządza siecią
między urządzeniem użytkownika a poszczególnymi usługami Google.
Jednak nowszy interfejs GoogleApi
i jego implementacje są łatwiejsze do wdrożenia
i są preferowanym sposobem dostępu do interfejsów API Usług Google Play.
Zapoznaj się z artykułem Uzyskiwanie dostępu do interfejsów API Google.
Z tego przewodnika dowiesz się, jak:
- Automatycznie zarządzaj połączeniem z Usługami Google Play.
- Wykonywanie synchronicznych i asynchronicznych wywołań interfejsu API do dowolnych Usług Google Play.
- ręcznie zarządzać połączeniem z Usługami Google Play w tych rzadkich przypadkach, niezbędną. Więcej informacji znajdziesz w artykule Połączenia zarządzane ręcznie.
Na początek zainstaluj bibliotekę usług Google Play (wersja 15 lub nowsza) dla pakietu Android SDK. W razie potrzeby wykonaj czynności opisane w Skonfiguruj pakiet SDK Usług Google Play.
Uruchamianie połączenia zarządzanego automatycznie
Po połączeniu projektu z biblioteką Usług Google Play utwórz instancję usługi
GoogleApiClient
za pomocą
GoogleApiClient.Builder
Interfejsy API w Twoich aktywnościach
onCreate()
.
GoogleApiClient.Builder
klasa udostępnia metody umożliwiające określenie interfejsów API Google, których chcesz użyć,
Zakresy protokołu OAuth 2.0. Oto przykładowy kod, który tworzy
Instancja GoogleApiClient
łącząca się z usługą Dysk Google:
GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this) .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */) .addApi(Drive.API) .addScope(Drive.SCOPE_FILE) .build();
Do jednego zestawu możesz dodać wiele interfejsów API i wiele zakresów.
GoogleApiClient
dołączając dodatkowe wywołania do addApi()
i addScope()
.
Ważne: jeśli dodajesz interfejs API Wearable
razem z innymi interfejsami API do
GoogleApiClient
na urządzeniach, które działają, mogą wystąpić błędy połączenia z klientem
nie mają zainstalowanej aplikacji Wear OS. Do
uniknąć błędów połączenia, wywołaj metodę addApiIfAvailable()
i przekaż ją
interfejs API Wearable
, aby umożliwić klientowi sprawną obsługę brakujących
API. Więcej informacji znajdziesz w artykule na temat uzyskiwania dostępu do interfejsu Wearable API.
Aby rozpocząć automatycznie zarządzane połączenie, musisz podać
wdrożenie w narzędziu OnConnectionFailedListener
może otrzymywać nierozwiązane błędy połączenia. Gdy Twoje konto będzie zarządzane automatycznie
Instancja GoogleApiClient
próbuje połączyć się z interfejsami API Google, automatycznie
interfejsu wyświetlacza, aby spróbować naprawić możliwe błędy połączeń (na przykład
Usługi Google Play wymagają aktualizacji). Jeśli wystąpi błąd, którego nie można
rozwiązany, zadzwonimy pod numer
onConnectionFailed()
Możesz też określić opcjonalną implementację interfejsu ConnectionCallbacks
, jeśli aplikacja musi wiedzieć, kiedy
nawiązano lub zawieszone jest automatycznie zarządzane połączenie. Jeśli na przykład:
aplikacja wykonuje wywołania do zapisu danych w interfejsach API Google, które powinny być wywoływane
dopiero po wywołaniu metody onConnected()
.
Oto przykładowe działanie, które implementuje interfejsy wywołania zwrotnego oraz dodaje i przekaż je do klienta interfejsu API Google:
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 // ... } }
Instancja GoogleApiClient
połączy się automatycznie po Twojej aktywności
zadzwoni do: onStart()
i rozłącz po rozmowie onStop()
.
Aplikacja może od razu zacząć tworzyć
żądania odczytu do interfejsów API Google po skompilowaniu GoogleApiClient
, bez
oczekiwanie na zakończenie połączenia.
Komunikacja z usługami Google
Po nawiązaniu połączenia klient będzie mógł wykonywać wywołania odczytu i zapisu za pomocą interfejsów API dotyczących konkretnej usługi w
które zostały autoryzowane przez aplikację, zgodnie z interfejsami API i zakresami dodanymi do
GoogleApiClient
.
Uwaga: zanim zaczniesz dzwonić do określonych usług Google, być może musisz najpierw zarejestrować w Google Developer Console. Instrukcje znajdziesz w odpowiednich dla używanego interfejsu API, np. Dysk Google lub Logowanie przez Google.
Gdy wykonujesz żądanie odczytu lub zapisu przy użyciu GoogleApiClient
, klient interfejsu API zwraca obiekt PendingResult
, który reprezentuje żądanie.
Dzieje się to natychmiast przed dostarczeniem żądania do usługi Google, z której wywołuje Twoja aplikacja.
Oto przykładowa prośba o odczytanie pliku z Dysku Google, który zawiera
Obiekt PendingResult
:
Query query = new Query.Builder() .addFilter(Filters.eq(SearchableField.TITLE, filename)); PendingResult<DriveApi.MetadataBufferResult> result = Drive.DriveApi.query(mGoogleApiClient, query);
Gdy aplikacja będzie miała obiekt PendingResult
,
aplikacja może następnie określić, czy żądanie ma być obsługiwane jako wywołanie asynchroniczne czy synchroniczne.
Wskazówka: aplikacja może dodawać do kolejki żądania odczytu, gdy nie jest połączona z Usługami Google Play. Dla:
na przykład aplikacja może wywoływać metody odczytu plików z Dysku Google niezależnie od tego, czy instancja GoogleApiClient
jest jeszcze połączona. Po nawiązaniu połączenia wykonywane są żądania odczytu umieszczone w kolejce. Jeśli aplikacja wywoła żądanie, żądania zapisu generują błąd
Usługi Google Play zapisują metody, gdy klient interfejsu API Google nie jest połączony.
Używanie wywołań asynchronicznych
Aby ustawić żądanie jako asynchroniczne, wywołaj
setResultCallback()
w: PendingResult
i podaj
implementacji
Interfejs ResultCallback
. Dla:
Oto żądanie wykonane asynchronicznie:
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. // ... } }); }
Gdy aplikacja otrzyma obiekt Result
w
wywołanie zwrotne onResult()
,
jest dostarczana jako instancja odpowiedniej podklasy określonej przez używany interfejs API;
na przykład
DriveApi.MetadataBufferResult
.
Korzystanie z wywołań synchronicznych
Jeśli chcesz, aby Twój kod był wykonywany w ściśle zdefiniowanej kolejności, np. dlatego, że w wyniku działania jednego z nich
jest wymagane jako argument dla innego, możesz ustawić żądanie synchroniczne, wywołując
await()
PendingResult
Spowoduje to zablokowanie wątku
i zwraca obiekt Result
, gdy
. Ten obiekt jest dostarczany jako instancja odpowiedniej podklasy określonej przez
interfejsu API, którego używasz, np.
DriveApi.MetadataBufferResult
Bo dzwonię pod numer await()
zablokuje wątek do czasu uzyskania wyniku, aplikacja nie powinna nigdy wysyłać synchronicznych żądań do interfejsów API Google
Wątek interfejsu. Aplikacja może utworzyć nowy wątek przy użyciu obiektu AsyncTask
i użyć tego wątku do wykonania żądania synchronicznego.
Poniższy przykład pokazuje, jak wysłać żądanie pliku do Dysku Google w ramach wywołania synchronicznego:
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 // ... } }
Uzyskaj dostęp do interfejsu Wearable API
Interfejs Wearable API zapewnia kanał komunikacji dla aplikacji działających na urządzeniach mobilnych i urządzeniach do noszenia. Interfejs API składa się ze zbioru obiektów danych, które system może wysyłać i synchronizować oraz detektorów, którzy za pomocą warstwy danych powiadamiają aplikacje o ważnych zdarzeniach. Interfejs Wearable API jest dostępny na urządzeniach z Androidem 4.3 (poziom interfejsu API 18) lub nowszym, połączone urządzenie do noszenia i aplikacja towarzysząca dla Wear OS jest zainstalowana na urządzeniu.
Korzystanie z samodzielnego interfejsu Wearable API
Jeśli Twoja aplikacja korzysta z interfejsu Wearable API, ale nie z innych interfejsów API Google, możesz go dodać przez
wywołanie metody addApi()
. Poniższy przykład pokazuje, jak dodać
Wearable API do instancji GoogleApiClient
:
GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this) .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */) .addApi(Wearable.API) .build();
Jeśli interfejs Wearable API jest niedostępny, połączenie z kontem
obejmują błąd Wearable API w tagu
API_UNAVAILABLE
.
Ten przykład pokazuje, jak sprawdzić, czy interfejs API do noszenia jest dostępny:
// 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 } // ... }
Używanie interfejsu Wearable API z innymi interfejsami API Google
Jeśli Twoja aplikacja używa interfejsu API do noszenia oraz innych interfejsów API Google, wywołaj metodę
addApiIfAvailable()
i przekaż ją za pomocą interfejsu API do noszenia, aby sprawdzić, czy jest ona dostępna. Możesz skorzystać z tej opcji, aby ułatwić aplikacji bezproblemową obsługę przypadków, w których interfejs API jest niedostępny.
Poniższy przykład pokazuje, jak uzyskać dostęp do interfejsu Wearable API wraz z Interfejs 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();
W powyższym przykładzie GoogleApiClient
może połączyć się z
Dysk Google bez połączenia z interfejsem API do noszenia, gdy jest on niedostępny. Po
podłączysz urządzenie GoogleApiClient
przed wywołaniem interfejsu API upewnij się, że interfejs Wearable API jest dostępny:
boolean wearAvailable = mGoogleApiClient.hasConnectedApi(Wearable.API);
Ignorowanie błędów połączenia z interfejsem API
Jeśli zadzwonisz pod numer addApi()
, a GoogleApiClient
nie będzie w stanie
nawiązać połączenie z tym interfejsem API, cała operacja połączenia dla tego klienta zakończy się niepowodzeniem
uruchamia wywołanie zwrotne onConnectionFailed()
.
Aby zignorować niepowodzenie połączenia interfejsu API, możesz użyć funkcji
addApiIfAvailable()
Jeśli do interfejsu API dodano element
addApiIfAvailable()
nie łączy się z powodu nieodwracalnego błędu
(np. API_UNAVAILABLE
na Wear),
że interfejs API jest usuwany z GoogleApiClient
, a klient przechodzi do
łączyć się z innymi interfejsami API. Jeśli jednak któreś z połączeń interfejsu API zakończy się błędem, który można naprawić (np.
intencji związanych z wyrażeniem zgody OAuth), operacja połączenia z klientem kończy się niepowodzeniem. Kiedy
przy użyciu połączenia zarządzanego automatycznie, GoogleApiClient
spróbuje
jak w miarę możliwości je usuwać. Podczas korzystania z połączenia zarządzanego ręcznie
obiekt ConnectionResult
zawierający intencję rozwiązania to
dostarczono na wywołanie zwrotne onConnectionFailed()
. Interfejs API
– błędy połączeń są ignorowane tylko wtedy, gdy nie można znaleźć rozwiązania problemu.
a interfejs API został dodany
dzięki addApiIfAvailable()
.
Aby dowiedzieć się, jak wdrożyć ręczne błędy połączenia
więcej informacji znajdziesz w sekcji Obsługa błędów połączeń.
Ponieważ interfejsy API zostały dodane z
Wartość addApiIfAvailable()
może nie być zawsze widoczna w połączonym
GoogleApiClient
, należy zabezpieczyć wywołania tych interfejsów API przez dodanie kontroli
za pomocą hasConnectedApi()
. Aby dowiedzieć się, dlaczego
nie udało się nawiązać połączenia, gdy cała operacja połączenia dla klienta zakończyła się sukcesem, wywołanie
getConnectionResult()
i pobierz kod błędu z
ConnectionResult
. Jeśli klient wywołuje interfejs API, gdy nie jest
po nawiązaniu połączenia z klientem nie uda się nawiązać połączenia
API_NOT_AVAILABLE
kodu stanu.
Jeśli interfejs API, który dodajesz za pomocą addApiIfAvailable()
, wymaga jednego lub
zakresów, dodaj je jako parametry w swoim raporcie.
addApiIfAvailable()
, a nie za pomocą
Metoda addScope()
. Zakresy dodane za pomocą tej metody mogą nie być żądane, jeśli interfejs API
nie ma połączenia przed uzyskaniem zgody OAuth, a zakresy dodane z parametrem
addScope()
są wymagane zawsze.
Połączenia zarządzane ręcznie
Z większości tego przewodnika dowiesz się, jak korzystać
enableAutoManage
do zainicjowania żądania
automatycznie zarządzane połączenie
z błędami naprawionymi automatycznie. Za prawie
jest to najlepszy i najłatwiejszy sposób łączenia się z interfejsami API Google
Aplikacja na Androida. Istnieją jednak sytuacje, w których warto użyć atrybutu
ręcznie zarządzane połączenie z interfejsami API Google w Twojej aplikacji:
- uzyskiwać dostęp do interfejsów API Google poza aktywnością lub zachować kontrolę nad interfejsem API; połączenie
- Aby dostosować obsługę i rozwiązywanie błędów połączenia
W tej sekcji znajdziesz przykłady takich i innych zaawansowanych zastosowań.
Rozpoczynanie połączenia zarządzanego ręcznie
Aby zainicjować ręcznie zarządzane połączenie z GoogleApiClient
, musisz
określ implementację interfejsów wywołań zwrotnych,
ConnectionCallbacks
i OnConnectionFailedListener
.
Te interfejsy otrzymują wywołania zwrotne w odpowiedzi na żądanie asynchroniczne
connect()
, gdy
połączenie z Usługami Google Play zostanie prawidłowo wykonane, nie powiedzie się lub zostanie zawieszone.
mGoogleApiClient = new GoogleApiClient.Builder(this) .addApi(Drive.API) .addScope(Drive.SCOPE_FILE) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build()
Przy ręcznym zarządzaniu połączeniem musisz wywołać metodę
connect()
oraz
disconnect()
w odpowiednich momentach cyklu życia aplikacji. W aktywności
kontekst, sprawdzoną metodą jest wywołanie connect()
w onStart()
aktywności
i disconnect()
w metodzie onStop()
Twojej aktywności.
connect()
oraz
disconnect()
metod
są wywoływane automatycznie podczas korzystania z połączenia zarządzanego automatycznie.
Jeśli używasz GoogleApiClient
do łączenia się z interfejsami API, które wymagają
takie jak Dysk Google czy Gry Google Play, jest duża szansa,
pierwsza próba nawiązania połączenia się nie uda i zostanie nawiązana połączenie do aplikacji
do onConnectionFailed()
dzięki SIGN_IN_REQUIRED
, ponieważ nie określono konta użytkownika.
Obsługa błędów połączeń
Gdy Twoja aplikacja otrzyma połączenie z numerem onConnectionFailed()
oddzwanianie, wybierz hasResolution()
w: ConnectionResult
obiektu. Jeśli wartość to „prawda”, aplikacja może poprosić użytkownika o natychmiastowe działanie w celu naprawienia błędu przez
dzwonię pod numer startResolutionForResult()
na obiekcie ConnectionResult
.
Metoda startResolutionForResult()
w tej sytuacji działa tak samo jak startActivityForResult()
,
i uruchamia działanie odpowiednie do kontekstu, które pomaga użytkownikowi usunąć błąd (np. działanie, które pomaga użytkownikowi
wybierz konto).
Jeśli hasResolution()
zwraca wartość false, aplikacja powinna wywołać
GoogleApiAvailability.getErrorDialog()
,
przez przekazanie kodu błędu do tej metody. Powoduje to zwrócenie
Dialog
od Google Play
odpowiednie usługi, których dotyczy błąd. Okno może zawierać po prostu komunikat wyjaśniający
błąd lub może udostępnić działanie, które rozwiąże błąd.
np. gdy użytkownik musi zainstalować nowszą wersję Usług Google Play.
Na przykład plik
Metoda wywołania zwrotnego onConnectionFailed()
powinna teraz wyglądać tak:
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(); } } }
Gdy użytkownik zakończy okno dialogowe wyświetlane przez
startResolutionForResult()
lub odrzuci komunikat podany przez użytkownika GoogleApiAvailability.getErrorDialog()
,
aktywność otrzymuje
onActivityResult()
wywołanie zwrotne z
RESULT_OK
kod wyniku.
Aplikacja będzie mogła wtedy zadzwonić
connect()
jeszcze raz.
Na przykład:
@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(); } } } }
W powyższym kodzie prawdopodobnie zauważyłeś(-aś) wartość logiczną mResolvingError
. Śledzi to
stanu aplikacji, gdy użytkownik rozwiązuje błąd, aby uniknąć powtarzających się prób rozwiązania tego samego problemu
. Na przykład okno wyboru konta wyświetla się, aby pomóc użytkownikowi
SIGN_IN_REQUIRED
użytkownik może obrócić ekran. To odtwarza Twoją aktywność i sprawia,
onStart()
a następnie wywołał je ponownie,
connect()
. Ten
powoduje kolejne wywołanie do
startResolutionForResult()
,
które tworzy kolejne okno wyboru konta przed tym istniejącym.
Ta wartość logiczna spełnia swoje zamierzone działanie tylko wtedy, gdy pozostaje w wielu instancjach aktywności. W następnej sekcji wyjaśniamy, jak zachować stan obsługi błędów w aplikacji pomimo innych działań użytkownika. ani zdarzeń na urządzeniu.
Zachowywanie stanu podczas rozwiązywania błędu
Aby uniknąć wykonywania kodu w
onConnectionFailed()
podczas poprzedniej próby rozwiązania błędu musisz zachować wartość logiczną, która
śledzi, czy aplikacja nie próbuje już naprawić błędu.
Jak widać w przykładzie powyżej, aplikacja powinna ustawiać wartość logiczną true
przy każdym wywołaniu
startResolutionForResult()
.
lub wyświetla okno dialogowe z
GoogleApiAvailability.getErrorDialog()
Następnie, gdy aplikacja otrzyma
RESULT_OK
w
onActivityResult()
wywołanie zwrotne, ustaw wartość logiczną na false
.
Aby śledzić wartości logiczne po ponownym uruchomieniu działania (np. gdy użytkownik obróci ekran),
zapisz wartość logiczną w zapisanych danych instancji przy użyciu funkcji
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); }
Następnie przywróć zapisany stan w okresie
onCreate()
:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ... mResolvingError = savedInstanceState != null && savedInstanceState.getBoolean(STATE_RESOLVING_ERROR, false); }
Teraz możesz bezpiecznie uruchamiać aplikację i ręcznie łączyć się z Usługami Google Play.