JeB*_*JeB 5 authentication android google-api android-emulator oauth-2.0
我正在尝试使用GoogleAccountCredential登录我的应用程序进行身份验证:
mGoogleAccountCredential = GoogleAccountCredential.usingOAuth2(context, Arrays.asList(Scopes.EMAIL, Scopes.PLUS_LOGIN));
mGoogleAccountCredential.setSelectedAccountName(accountName);
String token = mGoogleAccountCredential.getToken();
Run Code Online (Sandbox Code Playgroud)
它在真实设备上工作正常,但在android模拟器上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)
Run Code Online (Sandbox Code Playgroud)
GoogleApiAvailability.isGooglePlayServicesAvailable(context)
返回0)accountName
传递到setSelectedAccountName
(设置为"myuser@gmail.com"
)时设置并正确任何线索为什么它不在模拟器上工作?
UPD:
在谷歌的代码中挖掘了一下之后:问题发生在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;
}
Run Code Online (Sandbox Code Playgroud)
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");
}
Run Code Online (Sandbox Code Playgroud)
问题是getAccounts()
在模拟器上返回空数组.但是,在真实设备上,它会返回正确的列表.
嗯,事情总是比看起来容易。
感谢这篇文章和b1izzar指出了正确的答案。
我检查的所有真实设备都运行Android 5.1 Lollipop。
我检查的所有模拟器都运行Android 6.0 Marshmallow。
在Marshmallow上,即在我的模拟器上,在清单中指定权限是不够的GET_ACCOUNTS
。必须在运行时使用特定代码请求此权限:
请求权限:
Run Code Online (Sandbox Code Playgroud)// 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. } }
注意:在Marshmallow GET_ACCOUNTS
中,WRITE_CONTACTS
和READ_CONTACTS
权限位于同一权限组中,因此一旦READ_CONTACTS
授予,GET_ACCOUNTS
也将被授予。
注 2:在Android 中 Nougat GET_ACCOUNTS
已被弃用READ_CONTACTS
,因此即使GET_ACCOUNT
在Marshmallow中也可以使用它。
归档时间: |
|
查看次数: |
776 次 |
最近记录: |