web-dev-qa-db-fra.com

UserRecoverableAuthException: NeedPermission

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)
29
Sinigami

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);
}
... 
66
Claudio Cherubino

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;
       }
   }
12
Giorgio

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
7
pablofcn

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;
}
2
Gene Bo

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

1
toidiu

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);
}
0
Kazuyo