Google Play Hizmetleri kitaplığında sağlanan Google API'lerine (ör. Google ile Oturum Açma, Games ve Drive) erişmek için GoogleApiClient
("Google API İstemcisi") nesnesini kullanabilirsiniz. Google API istemcisi, Google Play Hizmetleri'ne ortak bir giriş noktası sağlar ve kullanıcının cihazı ile her Google hizmeti arasındaki ağ bağlantısını yönetir.
Ancak daha yeni GoogleApi
arayüzü ve uygulamalarının kullanımı daha kolaydır ve Play Hizmetleri API'lerine erişmek için tercih edilen yöntemdir.
Google API'lerine erişme başlıklı makaleyi inceleyin.
Bu kılavuzda aşağıdakileri nasıl yapacağınız açıklanmaktadır:
- Google Play Hizmetleri'ne bağlantınızı otomatik olarak yönetin.
- Google Play Hizmetleri'nden herhangi birine senkron ve asenkron API çağrıları gerçekleştirme
- Bunun gerekli olduğu nadir durumlarda Google Play Hizmetleri'ne olan bağlantınızı manuel olarak yönetin. Daha fazla bilgi için Manuel olarak yönetilen bağlantılar başlıklı makaleyi inceleyin.
Başlamak için önce Android SDK'nız için Google Play Hizmetleri kitaplığını (15 veya daha yeni bir düzeltme sürümü) yüklemeniz gerekir. Henüz yapmadıysanız Google Play Hizmetleri SDK'sını ayarlama başlıklı makaledeki talimatları uygulayın.
Otomatik olarak yönetilen bir bağlantı başlatma
Projeniz Google Play Hizmetleri kitaplığına bağlandıktan sonra, etkinliğinizin onCreate()
metodunda GoogleApiClient.Builder
API'lerini kullanarak GoogleApiClient
örneği oluşturun. GoogleApiClient.Builder
sınıfı, kullanmak istediğiniz Google API'lerini ve istediğiniz OAuth 2.0 kapsamlarını belirtmenize olanak tanıyan yöntemler sağlar. Aşağıda, Google Drive hizmetine bağlanan bir GoogleApiClient
örneği oluşturan bir kod örneği verilmiştir:
GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this) .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */) .addApi(Drive.API) .addScope(Drive.SCOPE_FILE) .build();
addApi()
ve addScope()
'a ek çağrılar ekleyerek aynı GoogleApiClient
alanına birden fazla API ve birden fazla kapsam ekleyebilirsiniz.
Önemli: Wearable
API'yi diğer API'lerle birlikte bir GoogleApiClient
'e ekleyecekseniz Wear OS uygulamasının yüklü olmadığı cihazlarda istemci bağlantısı hatalarıyla karşılaşabilirsiniz. Bağlantı hatalarını önlemek için addApiIfAvailable()
yöntemini çağırın ve istemcinizin eksik API'yi sorunsuz bir şekilde işlemesine izin vermek üzere Wearable
API'yi iletin. Daha fazla bilgi için Wearable API'ye erişim başlıklı makaleyi inceleyin.
Otomatik olarak yönetilen bir bağlantı başlatmak için çözülemeyen bağlantı hataları almak üzere OnConnectionFailedListener
arayüzü için bir uygulama belirtmeniz gerekir. Otomatik olarak yönetilen GoogleApiClient
örneğiniz Google API'lerine bağlanmaya çalıştığında, çözülebilir bağlantı hatalarını (ör. Google Play Hizmetleri'nin güncellenmesi gerekiyorsa) düzeltmeye çalışmak için kullanıcı arayüzünü otomatik olarak gösterir. Çözülemeyen bir hata oluşursa onConnectionFailed()
numaralı telefondan aranırsınız.
Uygulamanızın otomatik olarak yönetilen bağlantının ne zaman kurulduğunu veya askıya alındığını bilmesi gerekiyorsa ConnectionCallbacks
arayüzü için isteğe bağlı bir uygulama da belirtebilirsiniz. Örneğin, uygulamanız Google API'lerine veri yazmak için çağrı yapıyorsa bu çağrılar yalnızca onConnected()
yöntemi çağrıldıktan sonra başlatılmalıdır.
Geri çağırma arayüzlerini uygulayan ve bunları Google API istemcisinin içine ekleyen örnek bir etkinlik aşağıda verilmiştir:
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
örneğiniz, etkinliğiniz onStart()
'i aradıktan sonra otomatik olarak bağlanır ve onStop()
'ı aradıktan sonra bağlantıyı keser.
Uygulamanız, GoogleApiClient
oluşturulduktan sonra bağlantının tamamlanmasını beklemeden Google API'lerine hemen okuma isteği göndermeye başlayabilir.
Google Hizmetleri ile iletişim kurma
Bağlantı kurulduktan sonra istemciniz, GoogleApiClient
örneğinize eklediğiniz API'ler ve kapsamlar tarafından belirtildiği gibi, uygulamanızın yetkili olduğu hizmete özel API'leri kullanarak okuma ve yazma çağrıları yapabilir.
Not: Belirli Google hizmetlerine çağrı göndermeden önce uygulamanızı Google Developers Console'a kaydetmeniz gerekebilir. Talimatlar için kullandığınız API'ye (ör. Google Drive veya Google ile Oturum Açma) ait uygun başlangıç kılavuzuna bakın.
GoogleApiClient
kullanarak bir okuma veya yazma isteği gerçekleştirdiğinizde API istemcisi, isteği temsil eden bir PendingResult
nesnesi döndürür.
Bu işlem, istek uygulamanızın çağırdığı Google hizmetine ulaşmadan hemen önce gerçekleşir.
Örneğin, Google Drive'dan bir dosyayı okuma isteği aşağıdaki gibidir ve PendingResult
nesnesi sağlar:
Query query = new Query.Builder() .addFilter(Filters.eq(SearchableField.TITLE, filename)); PendingResult<DriveApi.MetadataBufferResult> result = Drive.DriveApi.query(mGoogleApiClient, query);
Uygulamanızda bir PendingResult
nesnesi oluşturulduktan sonra, istemin asenkron çağrı olarak mı yoksa senkron çağrı olarak mı işleneceğini belirtebilirsiniz.
İpucu: Uygulamanız, Google Play Hizmetleri'ne bağlı değilken okuma isteklerini sıraya ekleyebilir. Örneğin, uygulamanız GoogleApiClient
örneğinizin henüz bağlı olup olmadığına bakılmaksızın Google Drive'dan dosya okuma yöntemlerini çağırabilir. Bağlantı kurulduktan sonra, sıraya alınmış okuma istekleri yürütülür. Google API istemciniz bağlı değilken uygulamanız Google Play Hizmetleri yazma yöntemlerini çağırırsa yazma istekleri hata oluşturur.
Eşzamansız çağrıları kullanma
İsteği eşzamansız hale getirmek için PendingResult
üzerinde setResultCallback()
işlevini çağırın ve ResultCallback
arayüzünün bir uygulamasını sağlayın. Örneğin, asenkron olarak yürütülen istek aşağıda verilmiştir:
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. // ... } }); }
Uygulamanız onResult()
geri çağırma işlevinde bir Result
nesnesi aldığında bu nesne, kullandığınız API tarafından belirtilen uygun alt sınıfın bir örneği olarak (ör. DriveApi.MetadataBufferResult
) gönderilir.
Eşzamanlı çağrıları kullanma
Kodunuzun kesinlikle tanımlanmış bir sırada yürütülmesini istiyorsanız (ör. bir çağrının sonucunun başka bir çağrının bağımsız değişkeni olarak kullanılması gerektiği için) PendingResult
üzerinde await()
çağrısı yaparak isteğinizi eşzamanlı hale getirebilirsiniz. Bu işlem, ileti dizisini engeller ve istek tamamlandığında Result
nesnesini döndürür. Bu nesne, kullandığınız API tarafından belirtilen uygun alt sınıfın bir örneği olarak (ör. DriveApi.MetadataBufferResult
) yayınlanır.
await()
çağrısı, sonuç gelene kadar iş parçacığını engellediğinden uygulamanız hiçbir zaman kullanıcı arayüzü iş parçacığında Google API'lerine senkronize istek göndermemelidir. Uygulamanız, AsyncTask
nesnesi kullanarak yeni bir mesaj dizisi oluşturabilir ve senkronize isteği yapmak için bu mesaj dizisini kullanabilir.
Aşağıdaki örnekte, Google Drive'a senkron çağrı olarak dosya isteği gönderme işlemi gösterilmektedir:
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 // ... } }
Wearable API'ye erişme
Wearable API, el ve giyilebilir cihazlarda çalışan uygulamalar için bir iletişim kanalı sağlar. API, sistemin gönderip senkronize edebileceği bir veri nesnesi grubundan ve uygulamalarınızı bir veri katmanı kullanarak önemli etkinlikler hakkında bilgilendiren dinleyicilerden oluşur. Wearable API, Android 4.3 (API düzeyi 18) veya sonraki sürümleri çalıştıran cihazlarda, giyilebilir cihaz bağlıyken ve cihaza Wear OS tamamlayıcı uygulaması yüklendiğinde kullanılabilir.
Wearable API'yi bağımsız olarak kullanma
Uygulamanız diğer Google API'lerini değil, Wearable API'yi kullanıyorsa addApi()
yöntemini çağırarak bu API'yi ekleyebilirsiniz. Aşağıdaki örnekte, Wearable API'nin GoogleApiClient
örneğinize nasıl ekleneceği gösterilmektedir:
GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this) .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */) .addApi(Wearable.API) .build();
Wearable API'nin kullanılamadığı durumlarda, Wearable API içeren bağlantı istekleri API_UNAVAILABLE
hata koduyla başarısız olur.
Aşağıdaki örnekte, Wearable API'nin kullanılabilir olup olmadığı nasıl belirleneceği gösterilmektedir:
// 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'yi diğer Google API'leriyle kullanma
Uygulamanız diğer Google API'lerine ek olarak Wearable API'yi kullanıyorsa kullanılabilir olup olmadığını kontrol etmek için addApiIfAvailable()
yöntemini çağırın ve Wearable API'yi iletin. Uygulamanızın, API'nin kullanılamadığı durumları sorunsuz bir şekilde ele almasına yardımcı olmak için bu kontrolü kullanabilirsiniz.
Aşağıdaki örnekte, Drive API ile birlikte Wearable API'ye nasıl erişileceği gösterilmektedir:
// 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();
Yukarıdaki örnekte GoogleApiClient
, kullanılamıyorsa Wearable API'ye bağlanmadan Google Drive'a başarıyla bağlanabilir. GoogleApiClient
örneğinizi bağladıktan sonra, API çağrıları yapmadan önce Wearable API'nin kullanılabilir olduğundan emin olun:
boolean wearAvailable = mGoogleApiClient.hasConnectedApi(Wearable.API);
API Bağlantı Hatalarını Yoksayma
addApi()
çağrısı yaparsanız ve GoogleApiClient
bu API'ye başarılı bir şekilde bağlanamazsa söz konusu istemcinin bağlantı işleminin tamamı başarısız olur ve onConnectionFailed()
geri çağırma işlevi tetiklenir.
addApiIfAvailable()
kullanarak API bağlantısı hatasının yoksayılmasını sağlayabilirsiniz. addApiIfAvailable()
ile eklenen bir API, kurtarılamaz bir hata nedeniyle (ör. Wear için API_UNAVAILABLE
) bağlanamazsa bu API, GoogleApiClient
'inizden kaldırılır ve istemci diğer API'lere bağlanmaya devam eder. Ancak herhangi bir API bağlantısı, kurtarılabilir bir hatayla (OAuth kullanıcı rızası çözümleme amacı gibi) başarısız olursa istemci bağlantısı işlemi de başarısız olur. Otomatik olarak yönetilen bir bağlantı kullanıldığında GoogleApiClient
mümkün olduğunda bu tür hataları çözmeye çalışır. Manuel olarak yönetilen bir bağlantı kullanıldığında, çözüm amacı içeren bir ConnectionResult
, onConnectionFailed()
geri çağırma işlevine gönderilir. API bağlantısı hataları yalnızca hatanın çözümü yoksa ve API addApiIfAvailable()
ile eklendiyse yoksayılır.
Manuel bağlantı hatası yönetimini nasıl uygulayacağınızı öğrenmek için Bağlantı hatalarını yönetme başlıklı makaleyi inceleyin.
addApiIfAvailable()
ile eklenen API'ler bağlı GoogleApiClient
örneğinde her zaman mevcut olmayabileceğinden, hasConnectedApi()
kullanarak bir kontrol ekleyerek bu API'lere yapılan çağrıları korumanız gerekir. İstemci için bağlantı işleminin tamamı başarılı olduğunda belirli bir API'nin neden bağlanamadığını öğrenmek için getConnectionResult()
çağrısını yapın ve ConnectionResult
nesnesinden hata kodunu alın. İstemciniz istemciye bağlı değilken bir API'yi çağırırsa çağrı API_NOT_AVAILABLE
durum koduyla başarısız olur.
addApiIfAvailable()
aracılığıyla eklediğiniz API bir veya daha fazla kapsam gerektiriyorsa bu kapsamları addScope()
yöntemini kullanmak yerine addApiIfAvailable()
yöntem çağrınıza parametre olarak ekleyin. Bu yaklaşım kullanılarak eklenen kapsamlar, OAuth izni alınmadan önce API bağlantısı başarısız olursa istenmeyebilir. addScope()
ile eklenen kapsamlar ise her zaman istenir.
Manuel olarak yönetilen bağlantılar
Bu kılavuzun büyük bir kısmı, otomatik olarak çözülen hatalarla otomatik olarak yönetilen bir bağlantı başlatmak için enableAutoManage
yönteminin nasıl kullanılacağını gösterir. Neredeyse her durumda, Android uygulamanızdan Google API'lerine bağlanmanın en iyi ve en kolay yolu budur. Ancak uygulamanızda Google API'lerine manuel olarak yönetilen bir bağlantı kullanmak isteyeceğiniz bazı durumlar vardır:
- Bir etkinlik dışında Google API'lerine erişmek veya API bağlantısının kontrolünü elinde tutmak için
- Bağlantı hatası işleme ve çözümünü özelleştirme
Bu bölümde bu ve diğer ileri düzey kullanım alanlarına örnekler verilmiştir.
Manuel olarak yönetilen bir bağlantı başlatma
GoogleApiClient
ile manuel olarak yönetilen bir bağlantı başlatmak için geri çağırma arayüzleri ConnectionCallbacks
ve OnConnectionFailedListener
için bir uygulama belirtmeniz gerekir.
Bu arayüzler, Google Play Hizmetleri ile bağlantı başarılı olduğunda, başarısız olduğunda veya askıya alındığında asenkron connect()
yöntemine yanıt olarak geri çağırma alır.
mGoogleApiClient = new GoogleApiClient.Builder(this) .addApi(Drive.API) .addScope(Drive.SCOPE_FILE) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build()
Bir bağlantıyı manuel olarak yönetirken connect()
ve disconnect()
yöntemlerini uygulamanızın yaşam döngüsünün doğru noktalarında çağırmanız gerekir. Bir etkinlik bağlamında en iyi uygulama, etkinliğinizin onStart()
yönteminde connect()
ve etkinliğinizin onStop()
yönteminde disconnect()
çağrısıdır.
Otomatik olarak yönetilen bir bağlantı kullanıldığında connect()
ve disconnect()
yöntemleri otomatik olarak çağrılır.
Google Drive veya Google Play Games gibi kimlik doğrulama gerektiren API'lere bağlanmak için GoogleApiClient
kullanıyorsanız ilk bağlantı denemenizin başarısız olma olasılığı yüksektir ve uygulamanız, kullanıcı hesabı belirtilmediği için SIGN_IN_REQUIRED
hatasıyla onConnectionFailed()
çağrısı alır.
Bağlantı hatalarını ele alma
Uygulamanız onConnectionFailed()
geri arama işlevini çağrıldığında, sağlanan ConnectionResult
nesnesinde hasResolution()
işlevini çağırmanız gerekir. Doğru döndürülürse uygulamanız, ConnectionResult
nesnesinde startResolutionForResult()
çağırarak kullanıcıdan hatayı çözmek için hemen işlem yapmasını isteyebilir.
startResolutionForResult()
yöntemi bu durumda startActivityForResult()
ile aynı şekilde davranır ve kullanıcının hatayı çözmesine yardımcı olan bağlama uygun bir etkinlik (ör. kullanıcının hesap seçmesine yardımcı olan bir etkinlik) başlatır.
hasResolution()
yanlış döndürürse uygulamanız, hata kodunu bu yönteme ileterek GoogleApiAvailability.getErrorDialog()
yöntemini çağırmalıdır. Bu işlem, Google Play hizmetleri tarafından sağlanan ve hataya uygun bir Dialog
döndürür. İletişim kutusu, hatayı açıklayan bir mesajın yanı sıra hatayı çözebilecek bir etkinliği başlatma işlemi de sağlayabilir (ör. kullanıcının Google Play Hizmetleri'nin daha yeni bir sürümünü yüklemesi gerektiğinde).
Örneğin, onConnectionFailed()
geri çağırma yönteminiz artık şöyle görünecektir:
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(); } } }
Kullanıcı startResolutionForResult()
tarafından sağlanan iletişim kutusunu tamamladıktan veya GoogleApiAvailability.getErrorDialog()
tarafından sağlanan mesajı kapattıktan sonra etkinliğiniz, RESULT_OK
sonuç kodunu içeren onActivityResult()
geri çağırma çağrısını alır.
Ardından uygulamanız connect()
'u tekrar arayabilir.
Örneğin:
@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(); } } } }
Yukarıdaki kodda mResolvingError
doğru/yanlış değerini fark etmişsinizdir. Bu sayede, kullanıcı hatayı çözerken aynı hatanın tekrar tekrar çözülmeye çalışılmasını önlemek için uygulama durumu izlenir. Örneğin, kullanıcının SIGN_IN_REQUIRED
hatasını çözmesine yardımcı olmak için hesap seçici iletişim kutusu gösterilirken kullanıcı ekranı döndürebilir. Bu işlem, etkinliğinizi yeniden oluşturur ve onStart()
yönteminizin tekrar çağrılmasına neden olur. connect()
yöntemi de tekrar çağrılır. Bu, startResolutionForResult()
işlevinin tekrar çağrılmasına neden olur. Bu çağrı, mevcut hesap seçici iletişim kutusunun önüne başka bir hesap seçici iletişim kutusu oluşturur.
Bu boole değeri, yalnızca etkinlik örnekleri arasında kalıcıysa amaçlanan amacını yerine getirir. Sonraki bölümde, cihazda gerçekleşen diğer kullanıcı işlemlerine veya etkinliklere rağmen uygulamanızın hata işleme durumunu nasıl koruyacağınız açıklanmaktadır.
Hataları çözerken durumu koruma
Bir hatayı çözmeyle ilgili önceki bir deneme devam ederken onConnectionFailed()
kodunun yürütülmesini önlemek için uygulamanızın bir hatayı çözmeye çalışıp çalışmadığını izleyen bir boole değişkeni tutmanız gerekir.
Yukarıdaki kod örneğinde gösterildiği gibi, uygulamanız startResolutionForResult()
işlevini her çağırdığında veya GoogleApiAvailability.getErrorDialog()
adresinden iletişim kutusunu her gösterdiğinde bir boole değerini true
olarak ayarlamalıdır.
Ardından, uygulamanız onActivityResult()
geri çağırma işlevinde RESULT_OK
aldığında boole değerini false
olarak ayarlayın.
Etkinliğin yeniden başlatılması sırasında (ör. kullanıcı ekranı döndürdüğünde) boole değerini takip etmek için onSaveInstanceState()
kullanarak boole değerini etkinliğin kayıtlı örnek verilerine kaydedin:
private static final String STATE_RESOLVING_ERROR = "resolving_error"; @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(STATE_RESOLVING_ERROR, mResolvingError); }
Ardından, onCreate()
sırasında kaydedilen durumu kurtarın:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ... mResolvingError = savedInstanceState != null && savedInstanceState.getBoolean(STATE_RESOLVING_ERROR, false); }
Artık uygulamanızı güvenli bir şekilde çalıştırmaya ve Google Play Hizmetleri'ne manuel olarak bağlanmaya hazırsınız.