5

मैं अपने आवेदन प्रमाणीकरण के लिए GoogleAccountCredential का उपयोग कर में प्रवेश करने की कोशिश कर रहा हूँ पर OAuth 2.0 पहुँच टोकन प्राप्त करने में विफल:एंड्रॉयड एमुलेटर

mGoogleAccountCredential = GoogleAccountCredential.usingOAuth2(context, Arrays.asList(Scopes.EMAIL, Scopes.PLUS_LOGIN)); 
mGoogleAccountCredential.setSelectedAccountName(accountName); 
String token = mGoogleAccountCredential.getToken(); 

यह असली उपकरणों पर बस ठीक काम करता है, लेकिन एंड्रॉयड एमुलेटर पर mGoogleAccountCredential.getToken() विफल रहता है

java.lang.IllegalArgumentException: the name must not be empty: null 
03-01 19:41:31.604 3203-3361/com.myapp W/System.err:  at android.accounts.Account.<init>(Account.java:48) 
03-01 19:41:31.604 3203-3361/com.myapp W/System.err:  at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source) 
03-01 19:41:31.604 3203-3361/com.myapp W/System.err:  at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential.getToken(GoogleAccountCredential.java:255) 
  • Google Play वर्तमान सेवा एमुलेटर पर (GoogleApiAvailability.isGooglePlayServicesAvailable(context) रिटर्न 0)
  • +०१२३५१६४१०६१: निम्न अपवादों के साथ
  • accountName सेट कर दिया जाता है और सही जब setSelectedAccountName ("[email protected]" के लिए सेट)
  • सभी अनुमतियाँ, dependecies को पारित कर दिया और विन्यास परियोजना में मौजूद
(तथ्य की बात के रूप में, यह सब वास्तविक उपकरणों पर काम करता है)

कोई सुराग क्यों यह एमुलेटर पर काम नहीं कर रहा है?

युपीडी:
गूगल के कोड में थोड़ा खुदाई के बाद: मुद्दा setSelectedAccountName(accountName) विधि में होता है। यह विधि GoogleAccountManager से उसे दिए गए खाते के नाम से जुड़े खाते को देने के लिए कहती है। कोई ऐसा कोई खाता नहीं है, तो खाता नाम null करने के लिए सेट किया जा रहा है:

public final GoogleAccountCredential setSelectedAccountName(String accountName) { 
    selectedAccount = accountManager.getAccountByName(accountName); 
    // check if account has been deleted 
    this.accountName = selectedAccount == null ? null : accountName; 
    return this; 
    } 

AccountManager, बारी में, सभी मौजूदा खाते पर चला जाता है और दिए गए खाते के नाम के लिए उनके नाम है। यदि मिलान है, उपयुक्त खाता लौटा दिया जाता है:

public Account getAccountByName(String accountName) { 
    if (accountName != null) { 
     for (Account account : getAccounts()) { 
     if (accountName.equals(account.name)) { 
      return account; 
     } 
     } 
    } 
    return null; 
    } 

    public Account[] getAccounts() { 
    return manager.getAccountsByType("com.google"); 
    } 

बात यह है कि एमुलेटर पर getAccounts() रिटर्न खाली सरणी। एक असली डिवाइस पर, हालांकि, यह एक उचित सूची देता है।

+0

क्या आप Google API सिस्टम छवि का उपयोग करते हैं? – Anthony

+0

हां, मैंने इसे अपने प्रश्न – meltedspark

+0

में निर्दिष्ट किया है बस सुनिश्चित करने के लिए (जैसा कि मुझे इस विषय में गहरा अनुभव नहीं है), क्या आपने अपना वर्चुअल डिवाइस बनाने के लिए "Google एपीआई आइटम x86 सिस्टम छवि" का उपयोग किया था, न केवल "आइटम x86 सिस्टम छवि"? मैंने नहीं देखा कि आपने यह कहां निर्दिष्ट किया है (शायद अप्रत्यक्ष रूप से) – Anthony

उत्तर

2

ठीक है, हमेशा की तरह चीजें अपेक्षाकृत आसान होती हैं।
सही जवाब देने के लिए this पोस्ट और b1izzar पर धन्यवाद।

मेरे द्वारा चेक किए गए सभी वास्तविक डिवाइस एंड्रॉइड 5.1 लॉलीपॉप चल रहे हैं।
मेरे द्वारा चेक किए गए सभी अनुकरणकर्ता एंड्रॉइड 6.0 मार्शमलो चला रहे हैं।

मार्शमलो, यानी मेरे एमुलेटर पर, मैनिफेस्ट में GET_ACCOUNTS अनुमति निर्दिष्ट करने के लिए पर्याप्त नहीं है।

अनुरोध अनुमतियाँ:

// Here, thisActivity is the current activity 
if (ContextCompat.checkSelfPermission(thisActivity, 
       Manifest.permission.READ_CONTACTS) 
     != PackageManager.PERMISSION_GRANTED) { 

    // Should we show an explanation? 
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity, 
      Manifest.permission.READ_CONTACTS)) { 

     // Show an expanation to the user *asynchronously* -- don't block 
     // this thread waiting for the user's response! After the user 
     // sees the explanation, try again to request the permission. 

    } else { 

     // No explanation needed, we can request the permission. 

     ActivityCompat.requestPermissions(thisActivity, 
       new String[]{Manifest.permission.READ_CONTACTS}, 
       MY_PERMISSIONS_REQUEST_READ_CONTACTS); 

     // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an 
     // app-defined int constant. The callback method gets the 
     // result of the request. 
    } 
} 

नोट: में MarshmallowGET_ACCOUNTS, WRITE_CONTACTS और READ_CONTACTS अनुमतियाँ यह अनिवार्य एक विशिष्ट code साथ क्रम इस अनुमति को अनुरोध करने के लिए है एक ही अनुमति समूह में हैं, इसलिए एक बार READ_CONTACTS दिया गया है, GET_ACCOUNTS भी प्रदान किया जाता है।

नोट 2: में एंड्रॉयड नूगाGET_ACCOUNTS, deprecated है तो यह भावना भी Marshmallow में GET_ACCOUNT के बजाय READ_CONTACTS उपयोग करने के लिए बनाता है।

1

शायद एमुलेटर Google सेवाओं का पुराना संस्करण चला रहा है। ऐसा प्रतीत होता है कि नवीनतम संस्करण GoogleAuthException को IllegalArgumentException के विरोध में फेंक देगा।

API Doc

public String getToken() 
       throws IOException, 
         com.google.android.gms.auth.GoogleAuthException 
Returns an OAuth 2.0 access token. 
Must be run from a background thread, not the main UI thread. 

Throws: 
IOException 
com.google.android.gms.auth.GoogleAuthException 
+0

IllegalArgumentException एक रनटाइम अपवाद है, चेक किए गए एक नहीं। इसलिए यह फ़ंक्शन के हस्ताक्षर में निर्दिष्ट नहीं है। – meltedspark

+0

आप सही हैं, डरप। –

1

मुझे लगता है कि समस्या यह है कि आप क्योंकि Google Play सेवाओं एक एमुलेटर पर स्थापित नहीं किया जा सकता, विकास और परीक्षण के लिए एक भौतिक डिवाइस का उपयोग करना चाहिए है।

मैं एक और कारण नहीं दिख रहा है, लेकिन यहाँ आप एक code snippettasks-android-sample से लिया है कि यह भी GoogleAccountCredential उपयोग किया है।

+0

मैं उस छवि का उपयोग करता हूं जिसमें Google Play सेवाएं स्थापित हैं ("Google API सिस्टम छवि")। वास्तव में, मैं एम्यूलेटर पर अपने जीमेल में लॉगिन करने में सक्षम हूं। – meltedspark

संबंधित मुद्दे