GoogleApiClient के साथ Google API तक ऐक्सेस करना (अब सेवा में नहीं है)

आप GoogleApiClient ("Google API क्लाइंट") का इस्तेमाल कर सकते हैं 'Google Play सेवाएं' लाइब्रेरी में दिए गए Google API को ऐक्सेस करने के लिए आपत्ति जताएं (जैसे, Google साइन-इन, गेम, और Drive). Google API क्लाइंट, Google Play services का एक सामान्य एंट्री पॉइंट और नेटवर्क को मैनेज करना उपयोगकर्ता के डिवाइस और हर Google सेवा के बीच कनेक्शन.

हालांकि, नए GoogleApi इंटरफ़ेस और इसे लागू करने के तरीके Play services API को ऐक्सेस करने का पसंदीदा तरीका है. Google API ऐक्सेस करना देखें.

इस गाइड में बताया गया है कि:

  • Google Play services से, आपके कनेक्शन को अपने-आप मैनेज करने की सुविधा.
  • Google Play की किसी भी सेवा पर सिंक्रोनस और एसिंक्रोनस एपीआई कॉल करें.
  • बहुत कम मामलों में, Google Play सेवाओं से अपने कनेक्शन को मैन्युअल तरीके से मैनेज करें ज़रूरी है. ज़्यादा जानने के लिए, मैन्युअल तरीके से मैनेज किए गए कनेक्शन लेख पढ़ें.
इमेज 1: इलस्ट्रेशन में दिखाया गया है कि Google API क्लाइंट, किसी भी मौजूदा Google Play services से कनेक्ट करने और कॉल करने के लिए इंटरफ़ेस. जैसे, Google Play Games और Google Drive.

शुरू करने के लिए, आपको पहले Google Play services की लाइब्रेरी (15 या उसके बाद के वर्शन) इंस्टॉल करनी होगी Android SDK के लिए. अगर आपने अब तक ऐसा नहीं किया है, तो यहां दिए गए निर्देशों का पालन करें Google Play Services SDK टूल सेट अप करें.

अपने-आप मैनेज होने वाला कनेक्शन शुरू करना

अपने प्रोजेक्ट को Google Play services की लाइब्रेरी से लिंक करने के बाद, GoogleApiClient का इस्तेमाल करके GoogleApiClient.Builder आपकी ऐक्टिविटी में मौजूद एपीआई onCreate() तरीका. कॉन्टेंट बनाने GoogleApiClient.Builder क्लास में ऐसे तरीके दिए गए हैं जो आपको उन Google API को तय करने की सुविधा देते हैं जिनका आपको इस्तेमाल करना है और OAuth 2.0 के दायरे. यहां उदाहरण के तौर पर एक कोड दिया गया है, जिससे Google Drive सेवा से कनेक्ट करने वाला GoogleApiClient इंस्टेंस:

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

एक ही विज्ञापन में, एक से ज़्यादा एपीआई और एक से ज़्यादा स्कोप जोड़े जा सकते हैं GoogleApiClient addApi() पर अतिरिक्त कॉल जोड़कर और addScope().

अहम जानकारी: अगर Wearable API को किसी दूसरे एपीआई के साथ GoogleApiClient, आपको ऐसे डिवाइसों पर क्लाइंट कनेक्शन से जुड़ी गड़बड़ियां मिल सकती हैं जिन पर आपके डिवाइस में Wear OS ऐप्लिकेशन इंस्टॉल न हो. यहां की यात्रा पर हूं कनेक्शन की गड़बड़ियों से बचें, addApiIfAvailable() तरीके को कॉल करें और पास करें Wearable API का इस्तेमाल करके, अपने क्लाइंट को एपीआई. ज़्यादा जानकारी के लिए, Wearable API को ऐक्सेस करना लेख पढ़ें.

अपने-आप मैनेज होने वाला कनेक्शन शुरू करने के लिए, आपको OnConnectionFailedListener को लागू करने की प्रोसेस का इस्तेमाल करें. जब आपका कारोबार अपने-आप मैनेज होता है GoogleApiClient इंस्टेंस, Google API से कनेक्ट करने की कोशिश करता है. यह अपने-आप किसी भी रिज़ॉल्व किए जा सकने वाले कनेक्शन की गड़बड़ी को ठीक करने के लिए, यूज़र इंटरफ़ेस (यूआई) दिखाएं. उदाहरण के लिए, Google Play services को अपडेट करना होगा). अगर कोई ऐसी गड़बड़ी होती है जिसे समाधान हो जाता है, तो आपको onConnectionFailed().

अगर आपके ऐप्लिकेशन को यह जानने की ज़रूरत है कि कबConnectionCallbacks अपने-आप मैनेज होने वाला कनेक्शन बन या निलंबित हो. उदाहरण के लिए, अगर आपका ऐप्लिकेशन, Google API पर डेटा लिखने के लिए कॉल करता है. इसलिए, इनका इस्तेमाल शुरू करना चाहिए सिर्फ़ onConnected() तरीके को कॉल करने के बाद.

यहां एक ऐक्टिविटी का उदाहरण दिया गया है, जो कॉलबैक इंटरफ़ेस को लागू करती है और उन्हें 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

        // ...
    }
}

आपकी गतिविधि के बाद, आपका GoogleApiClient इंस्टेंस अपने-आप कनेक्ट हो जाएगा कॉल onStart() करता है और onStop() पर कॉल करने के बाद डिसकनेक्ट हो जाता है. आपका ऐप्लिकेशन तुरंत विज्ञापन बनाना शुरू कर सकता है GoogleApiClient बनाने के बाद, Google API को किए गए अनुरोध पढ़ें. कनेक्शन पूरा होने का इंतज़ार किया जा रहा है.

Google की सेवाओं से बातचीत करें

कनेक्ट करने के बाद, आपका क्लाइंट, सेवा के लिए बनाए गए एपीआई का इस्तेमाल करके, आपके जोड़े गए एपीआई और दायरों के मुताबिक, आपके ऐप्लिकेशन को अनुमति मिली हुई है GoogleApiClient इंस्टेंस.

ध्यान दें: Google की कुछ खास सेवाओं को कॉल करने से पहले, आपको अपना ऐप पर जाएं. निर्देशों के लिए, संबंधित जानकारी देखें आपके इस्तेमाल किए जा रहे एपीआई के लिए शुरुआती गाइड, जैसे कि Google Drive या Google साइन-इन.

GoogleApiClient का इस्तेमाल करके, पढ़ने या लिखने का अनुरोध करने पर एपीआई क्लाइंट, अनुरोध के बारे में बताने वाला PendingResult ऑब्जेक्ट दिखाता है. यह अनुरोध, आपके ऐप्लिकेशन की तरफ़ से कॉल की जा रही Google की सेवा को अनुरोध डिलीवर करने से ठीक पहले होता है.

उदाहरण के लिए, यहां Google Drive से एक ऐसी फ़ाइल को पढ़ने का अनुरोध दिया गया है जो PendingResult ऑब्जेक्ट:

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

आपके ऐप्लिकेशन में PendingResult ऑब्जेक्ट शामिल होने के बाद, तब आपका ऐप्लिकेशन यह तय कर सकता है कि अनुरोध को एसिंक्रोनस कॉल के तौर पर हैंडल किया जाए या सिंक्रोनस कॉल के तौर पर.

अहम जानकारी: आपका ऐप्लिकेशन, Google Play services से कनेक्ट न होने पर भी, मैसेज पढ़े जाने के अनुरोधों की सूची बना सकता है. इसके लिए उदाहरण के लिए, आपका ऐप्लिकेशन Google Drive से किसी फ़ाइल को पढ़ने के तरीकों को कॉल कर सकता है, भले ही आपका GoogleApiClient इंस्टेंस अभी तक कनेक्ट हो या नहीं. कनेक्शन बन जाने के बाद, सूची में शामिल पढ़ने के अनुरोध लागू होते हैं. अगर आपके ऐप्लिकेशन से आने वाले कॉल Google Play services, आपके Google API क्लाइंट के कनेक्ट न होने पर भी तरीके लिखती है.

एसिंक्रोनस कॉल का इस्तेमाल किया जा रहा है

अनुरोध को एसिंक्रोनस करने के लिए, कॉल करें setResultCallback() को PendingResult पर करो और किसी को लागू करना ResultCallback इंटरफ़ेस. इसके लिए उदाहरण के लिए, एसिंक्रोनस तरीके से किया गया अनुरोध यहां दिया गया है:

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.
            // ...
        }
    });
}

जब आपके ऐप्लिकेशन को Result ऑब्जेक्ट मिलता है onResult() कॉलबैक, इस्तेमाल किए जा रहे एपीआई के मुताबिक, इसे सही सब-क्लास के इंस्टेंस के तौर पर डिलीवर किया जाता है, जैसे कि DriveApi.MetadataBufferResult.

सिंक्रोनस कॉल का इस्तेमाल करना

अगर आप चाहते हैं कि आपका कोड पूरी तरह से तय किए गए क्रम में लागू हो, तो इसकी वजह यह हो सकती है कि किसी एक की तुलना में दूसरे तर्क के लिए कॉल करना ज़रूरी है, तो आप await() PendingResult. इससे थ्रेड ब्लॉक हो जाता है और Result ऑब्जेक्ट दिखाता है, जब अनुरोध पूरा होता है. इस ऑब्जेक्ट को सही सब-क्लास के इंस्टेंस के तौर पर डिलीवर किया जाता है. इसकी जानकारी उदाहरण के लिए, इस्तेमाल किया जा रहा एपीआई DriveApi.MetadataBufferResult.

await() पर कॉल करने की वजह से नतीजा आने तक थ्रेड को ब्लॉक करती है, तो आपके ऐप्लिकेशन को यूज़र इंटरफ़ेस (यूआई) थ्रेड. आपका ऐप्लिकेशन AsyncTask ऑब्जेक्ट का इस्तेमाल करके, नया थ्रेड बना सकता है और उस थ्रेड का इस्तेमाल सिंक्रोनस अनुरोध करने के लिए कर सकता है.

नीचे दिए गए उदाहरण में, Google Drive से सिंक्रोनस कॉल के तौर पर फ़ाइल का अनुरोध करने का तरीका बताया गया है:

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 ऐक्सेस करना

Wearable API, हैंडहेल्ड और पहने जाने वाले डिवाइसों पर चलने वाले ऐप्लिकेशन के लिए कम्यूनिकेशन चैनल उपलब्ध कराता है. एपीआई में डेटा ऑब्जेक्ट का एक सेट होता है, जिसे सिस्टम भेज सकता है और सिंक कर सकता है. ये ऐसे लिसनर हैं जो डेटा लेयर का इस्तेमाल करके, आपके ऐप्लिकेशन को अहम इवेंट की सूचना देते हैं. कॉन्टेंट बनाने Wearable API, Android 4.3 (एपीआई लेवल 18) या उसके बाद के वर्शन वाले डिवाइसों पर तब उपलब्ध होता है, जब पहने जाने वाला डिवाइस कनेक्ट हो गया है और Wear OS का साथी ऐप्लिकेशन चल रहा है डिवाइस पर मौजूद हो.

Wearable API का स्टैंड-अलोन इस्तेमाल करना

अगर आपका ऐप्लिकेशन Wearable API का इस्तेमाल करता है, लेकिन अन्य Google API का नहीं, तो आपके पास इस एपीआई को जोड़ने का विकल्प है addApi() तरीके को कॉल करें. नीचे दिए गए उदाहरण में, Wearable API को आपके GoogleApiClient इंस्टेंस में:

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

जिन स्थितियों में Wearable API उपलब्ध नहीं होता है वहां कनेक्शन से Wearable API को शामिल करना ज़रूरी नहीं है. API_UNAVAILABLE गड़बड़ी कोड.

यहां दिए गए उदाहरण में, यह पता लगाने का तरीका बताया गया है कि Wearable API उपलब्ध है या नहीं:

// 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 को अन्य Google API के साथ इस्तेमाल करना

अगर आपका ऐप्लिकेशन, अन्य Google API के साथ-साथ Wearable API का इस्तेमाल करता है, तो addApiIfAvailable() तरीका उपलब्ध है और यह देखने के लिए Wearable API में पास करें कि यह उपलब्ध है या नहीं. इस जांच का इस्तेमाल करके, अपने ऐप्लिकेशन को उन मामलों में बेहतर तरीके से हैंडल करने में मदद मिल सकती है जहां एपीआई उपलब्ध नहीं है.

नीचे दिया गया उदाहरण, Wearable API को 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();

ऊपर दिए गए उदाहरण में, GoogleApiClient Google Drive के उपलब्ध न होने पर, उसे Wearable API से कनेक्ट नहीं किया गया. इस तारीख के बाद आप अपने GoogleApiClient को कनेक्ट करते हैं उदाहरण के लिए, एपीआई कॉल करने से पहले पक्का करें कि Wearable API उपलब्ध हो:

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

API कनेक्शन विफलताओं को अनदेखा करना

अगर addApi() को कॉल किया जाता है और GoogleApiClient, उस एपीआई से कनेक्ट नहीं हो पाता है, तो उस क्लाइंट के लिए पूरा कनेक्शन ऑपरेशन फ़ेल हो जाता है और यह onConnectionFailed() कॉलबैक ट्रिगर करता है.

एपीआई कनेक्शन में हुई गड़बड़ी को रजिस्टर करने के लिए, addApiIfAvailable(). अगर किसी एपीआई को जोड़ा गया हो, तो addApiIfAvailable() ठीक नहीं की जा सकने वाली गड़बड़ी की वजह से कनेक्ट नहीं हो सका (जैसे, Wear के लिए API_UNAVAILABLE), एपीआई को आपके GoogleApiClient से हटा दिया जाता है और क्लाइंट आगे बढ़ जाता है अन्य एपीआई से कनेक्ट करते हैं. हालांकि, अगर कोई एपीआई कनेक्शन, दोबारा ठीक की जा सकने वाली गड़बड़ी (जैसे कि OAuth सहमति रिज़ॉल्यूशन इंटेंट), क्लाइंट से कनेक्ट नहीं हो सका. टास्क कब शुरू होगा अपने-आप मैनेज होने वाले कनेक्शन का इस्तेमाल करके, GoogleApiClient कोशिश करेगा कि ताकि गड़बड़ियों को ठीक किया जा सके. मैन्युअल तरीके से मैनेज किए जा रहे कनेक्शन का इस्तेमाल करते समय ConnectionResult में रिज़ॉल्यूशन इंटेंट शामिल है onConnectionFailed() कॉलबैक पर डिलीवर किया गया. एपीआई कनेक्शन टूट जाने पर, उसे अनदेखा कर दिया जाता है. हालांकि, ऐसा तब होता है, जब गड़बड़ी के लिए कोई समाधान न हो और एपीआई को जोड़ दिया गया addApiIfAvailable() के साथ. मैन्युअल तरीके से कनेक्शन न होने की समस्या को लागू करने का तरीका जानने के लिए हैंडलिंग के दौरान, कनेक्शन की गड़बड़ियां मैनेज करना देखें.

क्योंकि इसके साथ एपीआई जोड़े गए हैं ज़रूरी नहीं है कि addApiIfAvailable() हमेशा कनेक्ट किए गए डिवाइस में मौजूद हो GoogleApiClient उदाहरण के लिए, आपको एक चेक जोड़कर इन एपीआई पर होने वाले कॉल को सुरक्षित रखना चाहिए hasConnectedApi() का इस्तेमाल करके. यह पता लगाने के लिए कि क्लाइंट के लिए पूरा कनेक्शन ऑपरेशन सफल होने पर, कोई खास एपीआई कनेक्ट नहीं हो सका, तो getConnectionResult() पर क्लिक करें और ConnectionResult ऑब्जेक्ट. अगर आपका क्लाइंट, एपीआई को कॉल करता है, तो का उपयोग करते हैं, तो कॉल API_NOT_AVAILABLE स्टेटस कोड डालें.

अगर addApiIfAvailable() की मदद से जोड़े जा रहे एपीआई के लिए, एक या ज़्यादा दायरे हैं, तो उन दायरे को अपने कॉल करने के बजाय, addApiIfAvailable() तरीके को कॉल करें addScope() तरीका. इस तरीके का इस्तेमाल करके जोड़े गए दायरों के लिए अनुरोध नहीं किया जा सकता, अगर एपीआई OAuth सहमति पाने से पहले कनेक्शन काम नहीं करता, जबकि दायरे के साथ जोड़ा गया addScope() का अनुरोध हमेशा किया जाता है.

मैन्युअल रूप से मैनेज किए जा रहे कनेक्शन

इस गाइड के ज़्यादातर हिस्से में बताया गया है कि enableAutoManage तरीका अपने-आप मैनेज होने वाली गड़बड़ियों के साथ कनेक्शन. करीब सभी मामलों में, यह अपने Android ऐप्लिकेशन. हालांकि, कुछ ऐसी स्थितियाँ हैं जिनमें आपको आपके ऐप्लिकेशन में Google API से मैन्युअल रूप से मैनेज किया गया कनेक्शन:

  • किसी गतिविधि के बाहर Google API को ऐक्सेस करने या एपीआई पर कंट्रोल बनाए रखने के लिए कनेक्शन
  • कनेक्शन की गड़बड़ी को मैनेज करना और उसका समाधान करना

इस सेक्शन में, बेहतर इस्तेमाल के इन उदाहरणों और अन्य बेहतर तरीकों के उदाहरण दिए गए हैं.

मैन्युअल तरीके से मैनेज किया जा रहा कनेक्शन शुरू करना

GoogleApiClient से मैन्युअल तरीके से मैनेज किया गया कनेक्शन शुरू करने के लिए, आपको ऐसा करना होगा कॉलबैक इंटरफ़ेस के लिए एक लागू करने की जानकारी दें, ConnectionCallbacks और OnConnectionFailedListener. एसिंक्रोनस के रिस्पॉन्स में, इन इंटरफ़ेस को कॉलबैक मिलते हैं connect() तरीका इस्तेमाल करें, जब Google Play सेवाओं के साथ कनेक्शन टूट जाता है, काम नहीं करता या निलंबित हो जाता है.

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addApi(Drive.API)
            .addScope(Drive.SCOPE_FILE)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build()

मैन्युअल रूप से कनेक्शन प्रबंधित करते समय आपको connect() और disconnect() तरीके का इस्तेमाल करके तय किया गया है. किसी गतिविधि में आपकी गतिविधि के onStart() में connect() को कॉल करना, सबसे सही तरीका है तरीका और disconnect() को आपकी गतिविधि के onStop() तरीके में सबमिट करता है. connect() और disconnect() तरीके जब अपने-आप मैनेज होने वाले कनेक्शन का इस्तेमाल किया जाता है, तो उन्हें अपने-आप कॉल कर दिया जाता है.

अगर GoogleApiClient का इस्तेमाल, उन एपीआई से कनेक्ट करने के लिए किया जा रहा है जिनके लिए ज़रूरी है जैसे कि Google Drive या Google Play Games, तो इस बात की काफ़ी संभावना है कि पहली बार कनेक्ट करने की कोशिश फ़ेल हो जाएगी और आपके ऐप्लिकेशन पर कॉल आएगा onConnectionFailed() तक SIGN_IN_REQUIRED के साथ गड़बड़ी हो सकती है, क्योंकि उपयोगकर्ता खाता बताया नहीं गया था.

कनेक्शन से जुड़ी गड़बड़ियां ठीक करना

जब आपके ऐप्लिकेशन को onConnectionFailed() पर कॉल आता है कॉलबैक, आपको hasResolution() को कॉल करना चाहिए दिए गए ConnectionResult पर ऑब्जेक्ट है. अगर यह नतीजा सही है, तो आपका ऐप्लिकेशन उपयोगकर्ता से इस तरीके से गड़बड़ी को ठीक करने के लिए तुरंत कार्रवाई करने का अनुरोध कर सकता है: startResolutionForResult() को कॉल किया जा रहा है ConnectionResult ऑब्जेक्ट पर. startResolutionForResult() तरीका इस स्थिति में startActivityForResult() की तरह काम करता है और उस संदर्भ के हिसाब से कोई ऐसी गतिविधि लॉन्च करता है जिससे उपयोगकर्ता को गड़बड़ी को ठीक करने में मदद मिलती है. जैसे, कोई ऐसी गतिविधि जो उपयोगकर्ता को खाता चुनें).

अगर hasResolution() गलत वैल्यू दिखाता है, तो आपके ऐप्लिकेशन को कॉल करना चाहिए GoogleApiAvailability.getErrorDialog() इस तरीके में गड़बड़ी कोड पास करना. इससे Google Play की ओर से उपलब्ध कराया गया Dialog सही सेवाएं चुनें. डायलॉग में सिर्फ़ इसकी जानकारी देने वाला मैसेज दिया जा सकता है गड़बड़ी को ठीक किया जा सकता है या कोई ऐसी गतिविधि लॉन्च करने की वजह से भी गड़बड़ी को ठीक किया जा सकता है. (जैसे, जब उपयोगकर्ता को Google Play services का नया वर्शन इंस्टॉल करने की ज़रूरत हो).

उदाहरण के लिए, आपके onConnectionFailed() कॉलबैक का तरीका अब ऐसा दिखना चाहिए:

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();
        }
    }
}

जब उपयोगकर्ता, दिए गए डायलॉग बॉक्स को पूरा कर लेगा startResolutionForResult() या GoogleApiAvailability.getErrorDialog() के दिए गए मैसेज को खारिज कर देता है, आपकी गतिविधि को onActivityResult() इसके साथ कॉलबैक करें RESULT_OK नतीजे का कोड. इसके बाद, ऐप्लिकेशन से कॉल किया जा सकेगा फिर से connect() करें. उदाहरण के लिए:

@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();
            }
        }
    }
}

ऊपर दिए गए कोड में, शायद आपने बूलियन, mResolvingError देखा. यह ऐप्लिकेशन की स्थिति के दौरान उपयोगकर्ता गड़बड़ी को ठीक कर रहा हो, ताकि उसे बार-बार हल न किया जा सके गड़बड़ी. उदाहरण के लिए, खाता पिकर का डायलॉग दिखाया जाता है, ताकि उपयोगकर्ता को SIGN_IN_REQUIRED तो उपयोगकर्ता स्क्रीन को घुमा सकता है. इससे आपकी गतिविधि फिर से बनती है और onStart() तरीका फिर से कॉल किया, जो फिर से connect() फिर से. यह के नतीजे में, startResolutionForResult() इसकी मदद से, मौजूदा खाते के सामने एक और खाता पिकर डायलॉग बॉक्स बनाया जाता है.

यह बूलियन सिर्फ़ तब काम करता है, जब यह सभी गतिविधियों के लिए बना रहता है. अगले सेक्शन में बताया गया है कि उपयोगकर्ता की अन्य कार्रवाइयों के बावजूद, गड़बड़ी को मैनेज करने की स्थिति को कैसे बनाए रखा जा सकता है होने वाले सभी इवेंट दिखते हैं.

गड़बड़ी ठीक करते समय स्थिति बनाए रखना

कोड को एक्ज़ीक्यूट करने से बचने के लिए onConnectionFailed() जबकि किसी गड़बड़ी को ठीक करने की पिछली कोशिश जारी है, तो आपको एक बूलियन बनाए रखना होगा, जो यह ट्रैक करता है कि आपका ऐप्लिकेशन पहले से ही किसी गड़बड़ी को हल करने की कोशिश कर रहा है या नहीं.

जैसा कि ऊपर दिए गए कोड के उदाहरण में दिखाया गया है, हर बार आपके ऐप्लिकेशन को कॉल करते समय बूलियन को true पर सेट करना चाहिए startResolutionForResult() या इससे डायलॉग दिखाता है GoogleApiAvailability.getErrorDialog(). इसके बाद, जब आपके ऐप्लिकेशन को RESULT_OK onActivityResult() कॉलबैक के लिए, बूलियन को false पर सेट करें.

फिर से चालू होने पर बूलियन को ट्रैक करने के लिए (जैसे कि जब उपयोगकर्ता स्क्रीन को घुमाता है), बूलियन को इसका इस्तेमाल करके गतिविधि के सेव किए गए इंस्टेंस डेटा में सेव करें 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);
}

तब के दौरान सेव की गई स्थिति को रिकवर करें onCreate():

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // ...
    mResolvingError = savedInstanceState != null
            && savedInstanceState.getBoolean(STATE_RESOLVING_ERROR, false);
}

अब आप अपना ऐप्लिकेशन सुरक्षित तरीके से चलाने और Google Play सेवाओं से मैन्युअल रूप से कनेक्ट करने के लिए तैयार हैं.