我尝试按照教程:https://developers.google.com/android/guides/http-auth。
代码:
token = GoogleAuthUtil.getToken(getApplicationContext(),
mEmail, mScope);
清单:
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.NETWORK"/>
<uses-permission android:name="android.permission.USE_CREDENTIALS"/>
<uses-permission android:name="android.permission.INTERNET"/>
错误:
01-17 18:37:38.230: W/System.err(3689): com.google.android.gms.auth.UserRecoverableAuthException: NeedPermission
01-17 18:37:38.230: W/System.err(3689): at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
01-17 18:37:38.230: W/System.err(3689): at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
01-17 18:37:38.230: W/System.err(3689): at com.example.mgoogleauth.MainActivity$GetIOStreamTask.doInBackground(MainActivity.java:39)
01-17 18:37:38.230: W/System.err(3689): at com.example.mgoogleauth.MainActivity$GetIOStreamTask.doInBackground(MainActivity.java:1)
01-17 18:37:38.230: W/System.err(3689): at android.os.AsyncTask$2.call(AsyncTask.java:287)
01-17 18:37:38.230: W/System.err(3689): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
01-17 18:37:38.230: W/System.err(3689): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
01-17 18:37:38.230: W/System.err(3689): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
01-17 18:37:38.230: W/System.err(3689): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
01-17 18:37:38.230: W/System.err(3689): at java.lang.Thread.run(Thread.java:856)
答案 0 :(得分:69)
尝试按照适用于Android的云端硬盘快速入门,这是一个分步指南,展示了如何授权并将文件上传到云端硬盘:https://developers.google.com/drive/quickstart-android
更具体地说,看起来您没有捕获UserRecoverableException并触发让用户授权应用程序的意图。 您在快速入门示例中链接和处理的Google Play服务文档中记录了这一点,如下所示:
...
} catch (UserRecoverableAuthIOException e) {
startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
}
...
答案 1 :(得分:12)
official GoogleAuthUtil tutorial的方法getAndUseAuthTokenBlocking()很好地解释了如何处理异常:
// Example of how to use the GoogleAuthUtil in a blocking, non-main thread context
void getAndUseAuthTokenBlocking() {
try {
// Retrieve a token for the given account and scope. It will always return either
// a non-empty String or throw an exception.
final String token = GoogleAuthUtil.getToken(Context, String, String)(context, email, scope);
// Do work with token.
...
if (server indicates token is invalid) {
// invalidate the token that we found is bad so that GoogleAuthUtil won't
// return it next time (it may have cached it)
GoogleAuthUtil.invalidateToken(Context, String)(context, token);
// consider retrying getAndUseTokenBlocking() once more
return;
}
return;
} catch (GooglePlayServicesAvailabilityException playEx) {
Dialog alert = GooglePlayServicesUtil.getErrorDialog(
playEx.getConnectionStatusCode(),
this,
MY_ACTIVITYS_AUTH_REQUEST_CODE);
...
} catch (UserRecoverableAuthException userAuthEx) {
// Start the user recoverable action using the intent returned by
// getIntent()
myActivity.startActivityForResult(
userAuthEx.getIntent(),
MY_ACTIVITYS_AUTH_REQUEST_CODE);
return;
} catch (IOException transientEx) {
// network or server error, the call is expected to succeed if you try again later.
// Don't attempt to call again immediately - the request is likely to
// fail, you'll hit quotas or back-off.
...
return;
} catch (GoogleAuthException authEx) {
// Failure. The call is not expected to ever succeed so it should not be
// retried.
...
return;
}
}
答案 2 :(得分:7)
我有同样的错误,在我的情况下,我使用了错误的范围,我只是改变
https://www.googleapis.com/auth/plus.login
的
https://www.googleapis.com/auth/userinfo.profile
答案 3 :(得分:2)
在此文档页面上 https://developers.google.com/+/mobile/android/sign-in该示例对此异常有一个很好的解释。
特别是,应该注意这一行:
在第一次调用GoogleAuthUtil.getToken时,请求授权代码将始终抛出UserRecoverableAuthException
$('a').has('img').css('border-bottom', 'none')
答案 4 :(得分:1)
文档最近已更新,现在可以支持SDK M(请求权限)并显示OAuth对话框。
注意强> Google文档通常不是最新的,但在您报告问题时似乎会引起注意。这个例子更新了一周我发送反馈。因此,如果您看到一个不起作用的示例,请发送反馈!
https://developers.google.com/drive/v3/web/quickstart/android
答案 5 :(得分:0)
我发现这里的答案是被动的解决方案,而不是预防性的解决方案。
根据我很短的经验,在以下3种情况下会抛出UserRecoverableAuthException:NeedPermission:
登录Google时不要求#1适当范围
检查所请求的范围是否正确。在通过权限请求对话框进行身份验证过程后,Android应要求用户允许权限。这将防止在调用API时出现UserRecoverableAuthException。
GoogleSignInOptions o = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestScopes(new Scope(DriveScopes.DRIVE)) // request permission for Drive API
.requestScopes(new Scope(SheetsScopes.SPREADSHEETS)) // request permission for Sheets API
.requestEmail()
.build();
#2用户已拒绝权限
用户已在权限请求对话框上按下“拒绝”按钮。
#3用户已拒绝您应用程序的权限
对于Android 8.1.x,有一个菜单,您可以在其中拒绝单个应用程序的权限。不过,不确定其他版本。
Settings > Google > Connected apps
#2和#3不可避免地抛出UserRecoverableAuthException,因为它们是用户活动的结果。但是,尽管用户拒绝了,用下面的代码再次显示权限请求对话框不是没有意义吗?
} catch (UserRecoverableAuthIOException e) {
startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
}