Google Play services लाइब्रेरी में दिए गए Google API (जैसे, Google साइन इन, Games, और Drive) को ऐक्सेस करने के लिए, GoogleApiClient
("Google API क्लाइंट") ऑब्जेक्ट का इस्तेमाल किया जा सकता है. Google API क्लाइंट, Google Play services के लिए एक सामान्य एंट्री पॉइंट उपलब्ध कराता है. साथ ही, उपयोगकर्ता के डिवाइस और Google की हर सेवा के बीच नेटवर्क कनेक्शन को मैनेज करता है.
हालांकि, नए GoogleApi
इंटरफ़ेस और इसे लागू करने का तरीका इस्तेमाल करना आसान है. साथ ही, Play services के एपीआई को ऐक्सेस करने का यह सबसे पसंदीदा तरीका है.
Google API ऐक्सेस करना लेख पढ़ें.
इस गाइड में, इन कामों को करने का तरीका बताया गया है:
- Google Play services से अपने कनेक्शन को अपने-आप मैनेज करें.
- Google Play की किसी भी सेवा के लिए, सिंक्रोनस और असिंक्रोनस एपीआई कॉल करें.
- कुछ मामलों में, Google Play services से अपने कनेक्शन को मैन्युअल तरीके से मैनेज करना पड़ सकता है. ज़्यादा जानने के लिए, मैन्युअल तरीके से मैनेज किए जाने वाले कनेक्शन लेख पढ़ें.
शुरू करने के लिए, आपको अपने Android SDK के लिए, Google Play services लाइब्रेरी (रिविज़न 15 या उसके बाद का वर्शन) इंस्टॉल करना होगा. अगर आपने अब तक ऐसा नहीं किया है, तो Google Play Services SDK टूल सेट अप करें में दिए गए निर्देशों का पालन करें.
अपने-आप मैनेज होने वाला कनेक्शन शुरू करना
आपका प्रोजेक्ट, Google Play services लाइब्रेरी से लिंक होने के बाद, अपनी गतिविधि के onCreate()
तरीक़े में GoogleApiClient.Builder
एपीआई का इस्तेमाल करके, GoogleApiClient
का एक इंस्टेंस बनाएं. 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();
addApi()
और addScope()
में अतिरिक्त कॉल जोड़कर, एक ही GoogleApiClient
में कई एपीआई और कई स्कोप जोड़े जा सकते हैं.
अहम जानकारी: अगर GoogleApiClient
में अन्य एपीआई के साथ Wearable
एपीआई जोड़ा जा रहा है, तो उन डिवाइसों पर क्लाइंट कनेक्शन से जुड़ी गड़बड़ियां हो सकती हैं जिनमें Wear OS ऐप्लिकेशन इंस्टॉल नहीं है. कनेक्शन से जुड़ी गड़बड़ियों से बचने के लिए, addApiIfAvailable()
तरीका कॉल करें और Wearable
एपीआई को पास करें, ताकि आपका क्लाइंट, मौजूद न होने वाले एपीआई को आसानी से मैनेज कर सके. ज़्यादा जानकारी के लिए, 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 // ... } }
आपकी गतिविधि के onStart()
को कॉल करने के बाद, आपका GoogleApiClient
इंस्टेंस अपने-आप कनेक्ट हो जाएगा. साथ ही, onStop()
को कॉल करने के बाद, वह डिसकनेक्ट हो जाएगा.
GoogleApiClient
बनाने के बाद, आपका ऐप्लिकेशन तुरंत Google API को पढ़ने के अनुरोध करना शुरू कर सकता है. इसके लिए, उसे कनेक्शन पूरा होने का इंतज़ार नहीं करना पड़ता.
Google की सेवाओं के साथ इंटरैक्ट करना
कनेक्ट होने के बाद, आपका क्लाइंट सेवा के हिसाब से उन एपीआई का इस्तेमाल करके, डेटा पढ़ने और उसमें बदलाव करने के अनुरोध कर सकता है जिनके लिए आपके ऐप्लिकेशन को अनुमति मिली है. यह अनुमति, आपके GoogleApiClient
इंस्टेंस में जोड़े गए एपीआई और स्कोप के हिसाब से दी जाती है.
ध्यान दें: Google की कुछ सेवाओं को कॉल करने से पहले, आपको अपने ऐप्लिकेशन को Google Developer Console में रजिस्टर करना पड़ सकता है. निर्देशों के लिए, इस्तेमाल किए जा रहे एपीआई के लिए, शुरू करने से जुड़ी सही गाइड देखें. जैसे, 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 API क्लाइंट कनेक्ट न होने पर, Google Play services के लिखने के तरीकों को कॉल करता है, तो डेटा लिखने के अनुरोधों से गड़बड़ी का मैसेज जनरेट होता है.
एसिंक्रोनस कॉल का इस्तेमाल करना
अनुरोध को एसिंक्रोनस बनाने के लिए, PendingResult
पर setResultCallback()
को कॉल करें और 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. // ... } }); }
जब आपके ऐप्लिकेशन को onResult()
कॉलबैक में Result
ऑब्जेक्ट मिलता है, तो उसे सही सबक्लास के इंस्टेंस के तौर पर डिलीवर किया जाता है. यह डिलीवरी, इस्तेमाल किए जा रहे एपीआई के मुताबिक होती है. जैसे, DriveApi.MetadataBufferResult
.
सिंक किए गए कॉल का इस्तेमाल करना
अगर आपको अपना कोड तय किए गए क्रम में चलाना है, तो PendingResult
पर await()
को कॉल करके, अपने अनुरोध को सिंक किया जा सकता है. ऐसा तब करना पड़ता है, जब एक कॉल के नतीजे को दूसरे कॉल के लिए आर्ग्युमेंट के तौर पर इस्तेमाल करना हो. इससे थ्रेड ब्लॉक हो जाती है और अनुरोध पूरा होने पर, Result
ऑब्जेक्ट दिखाया जाता है. यह ऑब्जेक्ट, सही सबक्लास के इंस्टेंस के तौर पर डिलीवर किया जाता है. यह डिलीवरी, इस्तेमाल किए जा रहे एपीआई के मुताबिक होती है. उदाहरण के लिए, DriveApi.MetadataBufferResult
.
await()
को कॉल करने पर, नतीजा मिलने तक थ्रेड ब्लॉक हो जाता है. इसलिए, आपके ऐप्लिकेशन को यूज़र इंटरफ़ेस (यूआई) थ्रेड पर, Google API को कभी भी सिंक्रोनस अनुरोध नहीं करने चाहिए. आपका ऐप्लिकेशन, AsyncTask
ऑब्जेक्ट का इस्तेमाल करके नई थ्रेड बना सकता है. साथ ही, सिंक किए गए अनुरोध करने के लिए उस थ्रेड का इस्तेमाल कर सकता है.
यहां दिए गए उदाहरण में, Google Drive से फ़ाइल का अनुरोध सिंक्रोनस कॉल के तौर पर करने का तरीका बताया गया है:
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 को ऐक्सेस करना
Wearable API, हाथ में पकड़े जाने वाले और पहने जाने वाले डिवाइसों पर काम करने वाले ऐप्लिकेशन के लिए, कम्यूनिकेशन चैनल उपलब्ध कराता है. एपीआई में डेटा ऑब्जेक्ट का एक सेट होता है, जिसे सिस्टम भेज और सिंक कर सकता है. साथ ही, इसमें ऐसे लिसनर भी होते हैं जो डेटा लेयर का इस्तेमाल करके, आपके ऐप्लिकेशन को ज़रूरी इवेंट की सूचना देते हैं. Wearable API, Android 4.3 (एपीआई लेवल 18) या उसके बाद के वर्शन वाले डिवाइसों पर उपलब्ध है. इसके लिए ज़रूरी है कि डिवाइस से कोई स्मार्टवॉच कनेक्ट हो और उस पर Wear OS का साथी ऐप्लिकेशन इंस्टॉल हो.
Wearable API का स्टैंडअलोन तौर पर इस्तेमाल करना
अगर आपका ऐप्लिकेशन Wearable API का इस्तेमाल करता है, लेकिन अन्य Google API का नहीं, तो addApi()
तरीके को कॉल करके, इस एपीआई को जोड़ा जा सकता है. यहां दिए गए उदाहरण में, अपने GoogleApiClient
इंस्टेंस में Wearable API जोड़ने का तरीका बताया गया है:
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 } // ... }
Google के अन्य एपीआई के साथ Wearable API का इस्तेमाल करना
अगर आपका ऐप्लिकेशन, Google के अन्य एपीआई के साथ-साथ Wearable API का इस्तेमाल करता है, तो addApiIfAvailable()
तरीके को कॉल करें और Wearable API को पास करें. इससे यह पता चलेगा कि यह उपलब्ध है या नहीं. इस जांच का इस्तेमाल करके, अपने ऐप्लिकेशन को उन मामलों में बेहतर तरीके से मैनेज करने में मदद मिल सकती है जहां एपीआई उपलब्ध नहीं है.
इस उदाहरण में, Drive API के साथ-साथ Wearable 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
Wearable API के उपलब्ध न होने पर, Google Drive से कनेक्ट हो सकता है. GoogleApiClient
इंस्टेंस को कनेक्ट करने के बाद, एपीआई कॉल करने से पहले पक्का करें कि Wearable API उपलब्ध हो:
boolean wearAvailable = mGoogleApiClient.hasConnectedApi(Wearable.API);
एपीआई कनेक्टिविटी से जुड़ी गड़बड़ियों को अनदेखा करना
अगर addApi()
को कॉल किया जाता है और GoogleApiClient
उस एपीआई से कनेक्ट नहीं हो पाता है, तो उस क्लाइंट के लिए कनेक्शन का पूरा ऑपरेशन पूरा नहीं हो पाता और onConnectionFailed()
कॉलबैक को ट्रिगर करता है.
addApiIfAvailable()
का इस्तेमाल करके, एपीआई कनेक्शन से जुड़ी गड़बड़ी को रजिस्टर किया जा सकता है, ताकि उसे अनदेखा किया जा सके. अगर addApiIfAvailable()
के साथ जोड़ा गया कोई एपीआई, ठीक न की जा सकने वाली गड़बड़ी (जैसे, Wear के लिए API_UNAVAILABLE
) की वजह से कनेक्ट नहीं हो पाता है, तो उस एपीआई को आपके GoogleApiClient
से हटा दिया जाता है और क्लाइंट दूसरे एपीआई से कनेक्ट होने की प्रोसेस शुरू कर देता है. हालांकि, अगर कोई भी एपीआई कनेक्शन ठीक की जा सकने वाली गड़बड़ी (जैसे कि OAuth सहमति रिज़ॉल्यूशन इंटेंट) की वजह से पूरा नहीं होता है, तो क्लाइंट कनेक्ट करने की कार्रवाई पूरी नहीं होती. अपने-आप मैनेज होने वाले कनेक्शन का इस्तेमाल करने पर, GoogleApiClient
ऐसी गड़बड़ियों को ठीक करने की कोशिश करेगा. मैन्युअल तरीके से मैनेज किए जा रहे कनेक्शन का इस्तेमाल करने पर, onConnectionFailed()
कॉलबैक को रिज़ॉल्यूशन इंटेंट वाला ConnectionResult
डिलीवर किया जाता है. एपीआई कनेक्शन से जुड़ी गड़बड़ियों को सिर्फ़ तब अनदेखा किया जाता है, जब गड़बड़ी को ठीक करने का कोई तरीका न हो और एपीआई को addApiIfAvailable()
के साथ जोड़ा गया हो.
कनेक्शन से जुड़ी गड़बड़ी को मैन्युअल तरीके से मैनेज करने का तरीका जानने के लिए, कनेक्शन से जुड़ी गड़बड़ियों को मैनेज करना लेख पढ़ें.
ऐसा हो सकता है कि addApiIfAvailable()
के साथ जोड़े गए एपीआई, कनेक्ट किए गए GoogleApiClient
इंस्टेंस में हमेशा मौजूद न हों. इसलिए, आपको hasConnectedApi()
का इस्तेमाल करके जांच जोड़कर, इन एपीआई के कॉल को सुरक्षित रखना चाहिए. यह जानने के लिए कि क्लाइंट के लिए पूरा कनेक्शन ऑपरेशन पूरा होने के बाद भी, कोई खास एपीआई कनेक्ट क्यों नहीं हो पाया, getConnectionResult()
को कॉल करें और ConnectionResult
ऑब्जेक्ट से गड़बड़ी का कोड पाएं. अगर आपका क्लाइंट, एपीआई से कनेक्ट न होने पर उसे कॉल करता है, तो कॉल पूरा नहीं हो पाता और API_NOT_AVAILABLE
स्टेटस कोड दिखता है.
अगर addApiIfAvailable()
के ज़रिए जोड़े जा रहे एपीआई के लिए एक या उससे ज़्यादा स्कोप की ज़रूरत है, तो उन स्कोप को addScope()
तरीके का इस्तेमाल करने के बजाय, अपने addApiIfAvailable()
तरीके के कॉल में पैरामीटर के तौर पर जोड़ें. अगर OAuth की सहमति मिलने से पहले एपीआई कनेक्शन काम नहीं करता है, तो हो सकता है कि इस तरीके का इस्तेमाल करके जोड़े गए स्कोप का अनुरोध न किया जाए. वहीं, addScope()
का इस्तेमाल करके जोड़े गए स्कोप का अनुरोध हमेशा किया जाता है.
मैन्युअल तरीके से मैनेज किए जाने वाले कनेक्शन
इस गाइड के ज़्यादातर हिस्से में, अपने-आप मैनेज होने वाले कनेक्शन को शुरू करने के लिए, enableAutoManage
तरीके का इस्तेमाल करने का तरीका बताया गया है. इस तरीके से, गड़बड़ियां अपने-आप ठीक हो जाती हैं. ज़्यादातर मामलों में, अपने Android ऐप्लिकेशन से Google API से कनेक्ट करने का यह सबसे अच्छा और आसान तरीका है. हालांकि, कुछ मामलों में आपको अपने ऐप्लिकेशन में Google API से मैन्युअल तरीके से मैनेज किए जाने वाले कनेक्शन का इस्तेमाल करना पड़ सकता है:
- किसी गतिविधि के बाहर Google API ऐक्सेस करने या एपीआई कनेक्शन को कंट्रोल करने के लिए
- कनेक्शन से जुड़ी गड़बड़ी को मैनेज करने और उसे ठीक करने के तरीके को पसंद के मुताबिक बनाने के लिए
इस सेक्शन में, इन और अन्य बेहतर इस्तेमाल के उदाहरण दिए गए हैं.
मैन्युअल तरीके से मैनेज किया जाने वाला कनेक्शन शुरू करना
GoogleApiClient
से मैन्युअल तरीके से मैनेज किए जाने वाले कनेक्शन को शुरू करने के लिए, आपको कॉलबैक इंटरफ़ेस, ConnectionCallbacks
, और OnConnectionFailedListener
के लिए लागू करने का तरीका बताना होगा.
जब Google Play services से कनेक्ट किया जाता है, कनेक्ट नहीं हो पाता या निलंबित हो जाता है, तो इन इंटरफ़ेस को कॉलबैक मिलते हैं. ये कॉलबैक, एक साथ काम न करने वाले connect()
तरीके के जवाब में मिलते हैं.
mGoogleApiClient = new GoogleApiClient.Builder(this) .addApi(Drive.API) .addScope(Drive.SCOPE_FILE) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build()
कनेक्शन को मैन्युअल तरीके से मैनेज करते समय, आपको अपने ऐप्लिकेशन के लाइफ़साइकल के सही पॉइंट पर, connect()
और disconnect()
तरीकों को कॉल करना होगा. किसी गतिविधि के संदर्भ में, सबसे सही तरीका यह है कि गतिविधि के onStart()
तरीके में connect()
और गतिविधि के onStop()
तरीके में disconnect()
को कॉल किया जाए.
अपने-आप मैनेज होने वाले कनेक्शन का इस्तेमाल करने पर, connect()
और
disconnect()
तरीके अपने-आप कॉल हो जाते हैं.
अगर Google Drive या Google Play Games जैसे ऐसे एपीआई से कनेक्ट करने के लिए GoogleApiClient
का इस्तेमाल किया जा रहा है जिनके लिए पुष्टि की ज़रूरत होती है, तो हो सकता है कि कनेक्ट करने की आपकी पहली कोशिश पूरी न हो. साथ ही, आपके ऐप्लिकेशन को onConnectionFailed()
पर SIGN_IN_REQUIRED
वाली गड़बड़ी का कॉल मिलेगा, क्योंकि उपयोगकर्ता खाते की जानकारी नहीं दी गई थी.
कनेक्शन से जुड़ी समस्याएं हल करना
जब आपके ऐप्लिकेशन को onConnectionFailed()
कॉलबैक का कॉल मिलता है, तो आपको दिए गए ConnectionResult
ऑब्जेक्ट पर hasResolution()
कॉल करना चाहिए. अगर यह true दिखाता है, तो आपका ऐप्लिकेशन उपयोगकर्ता से गड़बड़ी को ठीक करने के लिए तुरंत कार्रवाई करने का अनुरोध कर सकता है. इसके लिए, ConnectionResult
ऑब्जेक्ट पर startResolutionForResult()
को कॉल करें.
इस स्थिति में, 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()
में कोड को लागू होने से रोकने के लिए, आपको एक बूलियन बनाए रखना होगा. इससे यह पता चलता है कि आपका ऐप्लिकेशन पहले से ही किसी गड़बड़ी को ठीक करने की कोशिश कर रहा है या नहीं.
ऊपर दिए गए कोड के उदाहरण में दिखाया गया है कि जब भी आपका ऐप्लिकेशन startResolutionForResult()
को कॉल करता है या GoogleApiAvailability.getErrorDialog()
से डायलॉग दिखाता है, तो उसे बोलियन को true
पर सेट करना चाहिए.
इसके बाद, जब आपके ऐप्लिकेशन को onActivityResult()
कॉलबैक में RESULT_OK
मिलता है, तो बूलियन को 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 services से मैन्युअल तरीके से कनेक्ट किया जा सकता है.