J'ai essayé de suivre le tutoriel: https://developers.google.com/Android/guides/http-auth .
Code:
token = GoogleAuthUtil.getToken(getApplicationContext(),
mEmail, mScope);
Manifeste:
<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"/>
Les erreurs:
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)
Essayez de suivre le guide de démarrage rapide de Drive pour Android. C’est un guide pas à pas qui explique comment autoriser et télécharger un fichier sur Drive: https://developers.google.com/drive/quickstart-Android
Pour être plus précis, il semble que vous n'attrapiez pas l'exception UserRecoverableException et ne souhaitiez pas que l'utilisateur autorise l'application . Ceci est documenté dans les documents Services Google Play que vous avez liés et traités dans l'exemple de démarrage rapide comme suit:
...
} catch (UserRecoverableAuthIOException e) {
startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
}
...
la méthode getAndUseAuthTokenBlocking () du tutoriel officiel de GoogleAuthUtil explique assez bien comment gérer l'exception:
// 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;
}
}
J'ai eu la même erreur, dans mon cas, j'utilisais une mauvaise portée, je viens de changer
https://www.googleapis.com/auth/plus.login
for
https://www.googleapis.com/auth/userinfo.profile
Sur cette page de documentation https://developers.google.com/+/mobile/Android/sign-in l'exemple fournit une bonne explication pour cette exception.
En particulier, il semble que cette ligne devrait être notée:
Demander un code d'autorisation lève toujours une exception UserRecoverableAuthException lors du premier appel à GoogleAuthUtil.getToken.
catch (UserRecoverableAuthException e) {
// Requesting an authorization code will always throw
// UserRecoverableAuthException on the first call to GoogleAuthUtil.getToken
// because the user must consent to offline access to their data. After
// consent is granted control is returned to your activity in onActivityResult
// and the second call to GoogleAuthUtil.getToken will succeed.
startActivityForResult(e.getIntent(), AUTH_CODE_REQUEST_CODE);
return;
}
Les documents ont été récemment mis à jour et fonctionnent désormais pour prendre en charge le SDK M (demande d'autorisation) et affichent également la boîte de dialogue OAuth.
NOTE Les documents Google ne sont souvent pas à jour, mais ils semblent faire attention lorsque vous signalez un problème. L’exemple a été mis à jour avec une semaine d’envoi de commentaires. Donc, si vous voyez un exemple qui ne fonctionne pas, envoyez vos commentaires!
https://developers.google.com/drive/v3/web/quickstart/Android
J'ai trouvé que les réponses ici sont des solutions passives et non préventives.
Selon ma très courte expérience, UserRecoverableAuthException: NeedPermission sera lancé dans les 3 cas suivants:
# 1 La portée appropriée n'est pas demandée lors de la connexion à Google
Vérifiez que les portées que vous demandez sont correctes. Android devrait demander à l'utilisateur d'autoriser l'autorisation après le processus d'authentification via le dialogue de demande d'autorisation. Cela empêchera UserRecoverableAuthException lors de l'appel de l'API.
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 L'utilisateur a refusé l'autorisation
L'utilisateur a appuyé sur le bouton "DENY" dans la boîte de dialogue de demande d'autorisation.
# 3 L'utilisateur a rejeté les autorisations de votre application
Pour Android 8.1.x, il existe un menu dans lequel vous pouvez refuser les autorisations pour des applications individuelles. Pas sûr des autres versions, cependant.
Settings > Google > Connected apps
UserRecoverableAuthException levée par # 2 et # 3 est inévitable parce que cela résulte de l'activité de l'utilisateur. Mais cela n'a-t-il pas de sens de montrer à nouveau le dialogue de demande d'autorisation avec le code ci-dessous malgré le rejet de l'utilisateur?
} catch (UserRecoverableAuthIOException e) {
startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
}