GoogleApiClient ile Google API'lerine erişme (kullanımdan kaldırıldı)

GoogleApiClient ("Google API İstemcisi") Google Play Hizmetleri kitaplığında sağlanan Google API'lerine erişmek için nesne (ör. Google ile Oturum Açma, Oyunlar ve Drive). Google API İstemcisi, Google Play Hizmetleri'ne ortak giriş noktası oluşturur ve ağı yönetir Google hizmetleri arasındaki bağlantıyı kurmak için kullanabilirsiniz.

Ancak, yeni GoogleApi arayüzü ve uygulamaları Play Hizmetleri API'lerine erişmenin tercih edilen yoludur. Google API'lerine erişme konusuna bakın.

Bu kılavuzda, aşağıdaki işlemleri nasıl yapacağınız gösterilmektedir:

  • Google Play Hizmetleri bağlantınızı otomatik olarak yönetin.
  • Google Play hizmetlerinden herhangi birine eşzamanlı ve eşzamansız API çağrıları gerçekleştirme.
  • Bunun gibi nadir durumlarda Google Play Hizmetleri ile bağlantınızı manuel olarak yönetin gerekir. Daha fazla bilgi edinmek için Manuel olarak yönetilen bağlantılar başlıklı makaleyi inceleyin.
ziyaret edin.
Şekil 1: Google API İstemcisi'nin gibi mevcut Google Play hizmetlerine bağlanmak ve bunlara çağrı yapmak için kullanılan arayüz Google Play Games ve Google Drive.

Başlamak için önce Google Play Hizmetleri kitaplığını yüklemeniz gerekir (düzeltme 15 veya sonraki sürümler) optimize edebilirsiniz. Henüz yapmadıysanız Google Play Hizmetleri SDK'sını kurun.

Otomatik olarak yönetilen bir bağlantı başlatma

Projeniz Google Play Hizmetleri kitaplığına bağlandıktan sonra şunun bir örneği oluşturun: GoogleApiClient şunu kullanarak: GoogleApiClient.Builder Etkinliğinizdeki API'ler onCreate() yöntemidir. İlgili içeriği oluşturmak için kullanılan GoogleApiClient.Builder class, kullanmak istediğiniz Google API'lerini ve reklam öğesi düzenleme isteklerinizi belirtmenize olanak tanıyan yöntemler sunar. OAuth 2.0 kapsamları. Burada, Google Drive hizmetine bağlanan GoogleApiClient örneği:

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

Aynı rapora birden fazla API ve kapsam ekleyebilirsiniz GoogleApiClient addApi() numarasına ek çağrılar ekleyerek ve addScope().

Önemli: Wearable API'yi diğer API'lerle birlikte bir GoogleApiClient şunu yapan cihazlarda istemci bağlantısı hatalarıyla karşılaşabilirsiniz: Wear OS uygulaması yüklü olmamalıdır. Alıcı: bağlantı hatalarından kaçının, addApiIfAvailable() yöntemini çağırın ve istemcinizin eksik olan sorunu incelikle ele almasını sağlamak için Wearable API API'ye gidin. Daha fazla bilgi için Giyilebilir cihaz API'sine erişme başlıklı makaleyi inceleyin.

Otomatik olarak yönetilen bir bağlantı başlatmak için OnConnectionFailedListener uygulanması arayüzünü kullanarak çözülemeyen bağlantı hataları almaya başlar. Otomatik yönetilen GoogleApiClient örneği, Google API'lerine bağlanmaya çalışıyor. Otomatik olarak çözülebilir bağlantı hatalarını düzeltmeyi denemek için ekran kullanıcı arayüzünü Google Play hizmetlerinin güncellenmesi gerekiyor). Gerçekleştirilemeyen bir hata oluşursa çözülmezse onConnectionFailed().

UygulamanızınConnectionCallbacks otomatik olarak yönetilen bağlantı kurulduğunda veya askıya alındığında. Örneğin, Uygulamanız, Google API'lerine veri yazmak için çağrı yapıyor. Bunların çağrılması gerekir yalnızca onConnected() yöntemi çağrıldıktan sonra.

Burada, geri çağırma arayüzlerini uygulayan ve Google API İstemcisi'ne gönderin:

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ğinizden sonra otomatik olarak bağlanır onStart() numaralı telefonu arar ve onStop() adlı kişiyi aradıktan sonra bağlantıyı keser. Uygulamanız hemen çıkmaya başlayabilir. GoogleApiClient oluşturulduktan sonra Google API'lerine okuma istekleri, ve bağlantının tamamlanmasını bekliyorsunuz.

Google hizmetleriyle iletişim kurma

Bağlantı kurulduktan sonra istemciniz, aşağıdakiler için hizmete özel API'leri kullanarak okuma ve yazma çağrıları yapabilir: uygulamanıza eklediğiniz API'ler ve kapsamlarda belirtildiği şekilde GoogleApiClient örneği.

Not: Belirli Google hizmetlerini aramadan önce inceleyebilirsiniz. Talimatlar için başlangıç kılavuzu, örneğin: Google Drive veya Google ile Oturum Açma.

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 teslim edilmeden hemen önce gerçekleşir.

Örneğin, aşağıda Google Drive'dan gelen bir dosyanın okunması isteği gösterilmektedir: PendingResult nesne:

Query query = new Query.Builder()
        .addFilter(Filters.eq(SearchableField.TITLE, filename));
PendingResult<DriveApi.MetadataBufferResult> result = Drive.DriveApi.query(mGoogleApiClient, query);

Uygulamanızda PendingResult nesnesi olduğunda, Böylece uygulamanız, isteğin eşzamansız çağrı olarak mı yoksa eşzamanlı çağrı olarak mı işleneceğini belirtebilir.

İpucu: Uygulamanız, Google Play Hizmetleri'ne bağlı değilken okuma isteklerini sıraya alabilir. Örneğin, Örneğin, GoogleApiClient örneğinizin bağlı olup olmadığından bağımsız olarak uygulamanız, Google Drive'dan dosya okumak için yöntemler çağırabilir. Bağlantı kurulduktan sonra sıraya alınmış okuma istekleri yürütülür. Uygulamanız çağırırsa yazma istekleri hata oluşturur Google API İstemciniz bağlı değilken Google Play Hizmetleri yazma yöntemleri kullanır.

Eşzamansız çağrıları kullanma

İsteği eşzamansız yapmak için şu çağrıyı yapın: setResultCallback() PendingResult üzerinde size bir uygulanması ResultCallback arayüzü. Örneğin, Örneğin, eşzamansız olarak yürütülen istek şu şekildedir:

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 şurada bir Result nesnesi aldığında: onResult() geri araması, kullandığınız API tarafından belirtilen uygun alt sınıfın bir örneği olarak sunulur. örneğin: DriveApi.MetadataBufferResult.

Eşzamanlı çağrıları kullanma

Kodunuzun kesin olarak tanımlanmış bir sırayla yürütülmesini istiyorsanız, belki bir sonucun sonucu çağrısının başka bir bağımsız değişken olarak kullanılması gerekiyorsa, await() PendingResult. Bu işlem ileti dizisini engeller veResult isteği yerine getirilir. Bu nesne, şu şekilde belirtilen uygun alt sınıfın bir örneği olarak yayınlanır: örneğin kullandığınız API DriveApi.MetadataBufferResult.

await() arandığı için sonuç gelene kadar iş parçacığını engellerse uygulamanız Kullanıcı arayüzü iş parçacığı. Uygulamanız, AsyncTask nesnesini kullanarak yeni bir ileti dizisi oluşturabilir ve eşzamanlı istekte bulunmak için bu iş parçacığını kullanabilir.

Aşağıdaki örnekte, eşzamanlı çağrı olarak Google Drive'a nasıl dosya isteği gönderileceği gösterilmektedir:

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'ye erişme

Giyilebilir API, elde kullanılan ve giyilebilir cihazlarda çalışan uygulamalar için bir iletişim kanalı sağlar. API, sistemin gönderip senkronize edebileceği bir veri nesnesi kümesinden oluşur ve önemli olaylarla ilgili uygulamalarınızı bilgilendiren dinleyiciler içerir. İlgili içeriği oluşturmak için kullanılan Giyilebilir API, Android 4.3 (API düzeyi 18) veya sonraki sürümleri çalıştıran cihazlarda aşağıdaki durumlarda kullanılabilir: giyilebilir bir cihazın bağlı olması ve Wear OS tamamlayıcı uygulaması yüklü olduğundan emin olun.

Giyilebilir API'yi bağımsız olarak kullanma

Uygulamanız Wearable API'yi kullanıyor ancak diğer Google API'lerini kullanmıyorsa bu API'yi şu şekilde ekleyebilirsiniz: addApi() yöntemini çağırın. Aşağıdaki örnekte, GoogleApiClient örneğinize Giyilebilir API:

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

Giyilebilir API'nin kullanılamadığı durumlarda, Giyilebilir API'nin API_UNAVAILABLE hata kodu.

Aşağıdaki örnekte, Wearable API'nin kullanılabilir olup olmadığının nasıl anlaşılacağı 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 addApiIfAvailable() yöntemini kullanın ve kullanılabilir olup olmadığını kontrol etmek için Giyilebilir 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, Giyilebilir API'ye ve 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();

Yukarıdaki örnekte, GoogleApiClient, Kullanılamıyorsa Giyilebilir API'ye bağlanmadan Google Drive'ı kullan. Şu tarihten sonra: GoogleApiClient cihazınızı bağlayın örneğin, API çağrıları yapmadan önce Giyilebilir API'nin kullanılabildiğinden emin olun:

boolean wearAvailable = mGoogleApiClient.hasConnectedApi(Wearable.API);

API Bağlantı Hatalarını Yoksayma

addApi() numaralı telefonu ararsanız ve GoogleApiClient şunları yapamazsa: API'ye başarıyla bağlandığında, söz konusu istemcinin tüm bağlantı işlemi başarısız olur ve onConnectionFailed() geri çağırmasını tetikler.

Bir API bağlantı hatasını yoksaymak için şunu kullanarak kaydedebilirsiniz: addApiIfAvailable(). addApiIfAvailable(), düzeltilemeyen bir hata nedeniyle bağlanamıyor (ör. Wear için API_UNAVAILABLE), bu API, GoogleApiClient devre dışı bırakılır ve istemci, diğer API'lere bağlanıyor. Ancak herhangi bir API bağlantısı kurtarılabilir bir hatayla (ör. OAuth izin çözümleme amacı) kullanıyorsa istemci bağlantı işlemi başarısız olur. Zaman GoogleApiClient, otomatik olarak yönetilen bir bağlantı kullanarak mümkün olan en iyi uygulamaları analiz etmeyi öğreteceğiz. Manuel olarak yönetilen bir bağlantı kullanırken Çözüm amacı içeren bir ConnectionResult onConnectionFailed() geri aramasına teslim edildi. API bağlantı hataları yalnızca hata için bir çözüm olmadığında yok sayılır ve API'ye addApiIfAvailable() ile. Manuel bağlantı hatasının nasıl uygulanacağını öğrenmek için Bağlantı hatalarını işleme başlıklı makaleye göz atın.

Çünkü API'ler addApiIfAvailable() her zaman bağlı cihazda bulunmayabilir GoogleApiClient örneği için bir onay işareti ekleyerek bu API'lere yapılan çağrıları korumanız gerekir. hasConnectedApi() ile. Arkadaş Bitkiler projesinin istemci için bağlantı işleminin tamamı başarılı olduğunda söz konusu API bağlanamadı. getConnectionResult() adresine gidip şu hata kodunu alın: ConnectionResult nesne olarak tanımlar. İstemciniz bir API çağırmıyorsa istemci bağlı değilse çağrı, API_NOT_AVAILABLE kullanabilirsiniz.

addApiIfAvailable() üzerinden eklediğiniz API için bir veya daha fazla kapsam varsa bu kapsamları addApiIfAvailable() yöntem çağrısı için addScope() yöntemini çağırın. API aşağıdaki durumlarda bu yaklaşım kullanılarak eklenen kapsamlar istenemez bağlantı, OAuth izni alınmadan önce başarısız olurken addScope() her zaman istenir.

Manuel olarak yönetilen bağlantılar

Bu kılavuzun büyük bir kısmı, enableAutoManage yöntemini kullanarak ve otomatik olarak yönetilen ve otomatik olarak çözülmüş hataları içeren bir bağlantı sağlar. Neredeyse Her durumda, bu, uygulamanızdan Google API'lerine bağlanmanın en iyi ve en kolay yoludur. Android uygulaması. Ancak, Uygulamanızda Google API'lerine manuel olarak yönetilen bağlantı:

  • Google API'lerine bir etkinlik dışında erişmek veya API'nin kontrolünü elinizde tutmak için aktarma
  • Bağlantı hatalarını işlemeyi ve çözümlemeyi özelleştirmek için

Bu bölümde bu ve diğer gelişmiş kullanım alanlarına örnekler verilmiştir.

Manuel olarak yönetilen bir bağlantı başlatma

GoogleApiClient ile manuel olarak yönetilen bağlantı başlatmak için geri çağırma arayüzleri için bir uygulama belirtirsiniz, ConnectionCallbacks ve OnConnectionFailedListener. Bu arayüzler, eşzamansız sinyallere yanıt olarak connect() yöntemini kullanarak Google Play hizmetleri bağlantısı başarılı olursa, başarısız olursa veya askıya alınırsa.

    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öntemlerine yer verebilir. Bir etkinlikte bağlam en iyi uygulama, etkinliğinizin onStart() bölümünde connect() işlevini çağırmaktır. yöntemini ve disconnect() etkinliğinizin onStop() yönteminde. connect() ve disconnect() yöntem otomatik olarak yönetilen bir bağlantı kullanılırken otomatik olarak çağrılır.

Gerekli olan API'lere bağlanmak için GoogleApiClient kullanıyorsanız Google Drive veya Google Play Games gibi bir kimlik doğrulama sistemi kullanıyorsanız ilk bağlantı denemeniz başarısız olacak ve uygulamanız bir çağrı alacak Hedef: onConnectionFailed() SIGN_IN_REQUIRED ile hatası (kullanıcı hesabı belirtilmediğinden).

Bağlantı hatalarını işleme

Uygulamanız onConnectionFailed() numarasına çağrı aldığında geri arama, hasResolution() numaralı telefonu aramalısınız sağlanan ConnectionResult nesnesini tanımlayın. Doğru değerini döndürürse uygulamanız, kullanıcıdan hatayı düzeltmek için gereken startResolutionForResult() aranıyor ConnectionResult nesnesinin üzerine getirin. startResolutionForResult() yöntemi bu durumda startActivityForResult() ile aynı şekilde davranırsa ve kullanıcının hatayı çözmesine yardımcı olan, bağlama uygun bir etkinliği (kullanıcının işlemini tamamlamasına yardımcı olan bir etkinlik gibi) hesap seçin).

hasResolution() ise false değerini döndürürse uygulamanız GoogleApiAvailability.getErrorDialog(), nasıl aktaracağımızı göreceğiz. Bu, Dialog, Google Play tarafından sağlanmıştır seçmeye çalışıyor. İletişim kutusunda hatayı giderebilir veya hatayı çözebilecek bir etkinlik başlatacak bir işlem 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öntemi artık şu şekilde görünmelidir:

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ı, tarafından sağlanan iletişim kutusunu tamamladıktan sonra startResolutionForResult() GoogleApiAvailability.getErrorDialog() tarafından sağlanan mesajı kapatır veya etkinliği her zaman onActivityResult() şununla geri arama: RESULT_OK sonuç kodu. Ardından uygulamanız Tekrar connect(). Ö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 boole değerini fark etmişsinizdir. Bu, Kullanıcı hatayı çözerken aynı uygulamayı tekrar tekrar denememek için uygulama durumu hatası. Örneğin, kullanıcının SIGN_IN_REQUIRED kullanıcı ekranı döndürebilir. Bu, etkinliğinizi yeniden oluşturur ve onStart() yöntemi sonra yeniden aranır ve ardından Tekrar connect(). Bu yeni bir çağrıyla sonuçlanır startResolutionForResult() Bu işlem, mevcut sepetin önünde başka bir hesap seçici iletişim kutusu oluşturur.

Bu boole, yalnızca etkinlik örneklerinde devam ederse amacına hizmet eder. Sonraki bölümde, diğer kullanıcı işlemlerine rağmen uygulamanızın hata işleme durumunu nasıl koruyacağınız açıklanmaktadır. etkinlikler de olabilir.

Bir hatayı çözümlerken durumu koruma

Kodun çalıştırılmaması için onConnectionFailed() daha önce hata düzeltme girişimi devam ederken uygulamanızın zaten bir hatayı çözmeye çalışıp çalışmadığını takip eder.

Yukarıdaki kod örneğinde gösterildiği gibi, uygulamanız her çağırdığında true değerine sahip bir boole ayarlamalıdır startResolutionForResult() veya GoogleApiAvailability.getErrorDialog(). Ardından, uygulamanız RESULT_OK onActivityResult() geri çağırma için boole'yi false olarak ayarlayın.

Etkinlik yeniden başlatmalarında (ör. kullanıcı ekranı döndürdüğünde) boole'yi takip etmek için boole'yi etkinliğin kaydedilen örnek verilerine kaydedin. 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);
}

Ardından, taşıma sırasında kaydedilen durumu kurtarın. onCreate():

@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.