wake-up-neo.com

UserRecoverableAuthException: NeedPermission

Ich habe versucht, dem Tutorial zu folgen: https://developers.google.com/Android/guides/http-auth .

Code:

token = GoogleAuthUtil.getToken(getApplicationContext(),
                        mEmail, mScope);

Manifest:

<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"/>

Fehler:

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

Folgen Sie dem Schnellstart von Drive für Android. Es wird Schritt für Schritt beschrieben, wie Sie eine Datei autorisieren und auf Drive hochladen: https://developers.google.com/drive/quickstart-Android

Genauer gesagt scheint es, als würden Sie die UserRecoverableException nicht abfangen und die Absicht auslösen, dass der Benutzer die App autorisiert. Dies wird in den Google Play Services-Dokumenten dokumentiert, die Sie verknüpft und im Schnellstartbeispiel wie folgt behandelt haben:

...
} catch (UserRecoverableAuthIOException e) {
  startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
}
... 
66

die Methode getAndUseAuthTokenBlocking () des offiziellen GoogleAuthUtil-Tutorials erklärt ziemlich gut, wie mit der Ausnahme umgegangen wird:

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

Ich hatte den gleichen Fehler. In meinem Fall habe ich einen falschen Bereich verwendet. Ich ändere nur

https://www.googleapis.com/auth/plus.login

for

https://www.googleapis.com/auth/userinfo.profile
7
pablofcn

Auf dieser Dokumentenseite https://developers.google.com/+/mobile/Android/sign-in Das Beispiel hat eine gute Erklärung für diese Ausnahme.

Im Besonderen sieht diese Zeile aus:

Beim Anfordern eines Autorisierungscodes wird beim ersten Aufruf immer UserRecoverableAuthException an GoogleAuthUtil.getToken ausgelöst

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

Die Dokumente wurden kürzlich aktualisiert und unterstützen nun SDK M (Berechtigungsanforderung) und zeigen das OAuth-Dialogfeld an.

NOTE Google Text & Tabellen sind häufig nicht auf dem neuesten Stand, scheinen jedoch aufmerksam zu sein, wenn Sie ein Problem melden. Das Beispiel wurde mit einer Woche aktualisiert, in der ich ein Feedback sendete. Wenn Sie also ein nicht funktionierendes Beispiel sehen, senden Sie uns ein Feedback!

https://developers.google.com/drive/v3/web/quickstart/Android

1
toidiu

Ich fand die Antworten hier passiv und nicht präventiv.
Aufgrund meiner sehr kurzen Erfahrung wird UserRecoverableAuthException: NeedPermission in den folgenden 3 Fällen ausgelöst:

# 1 Geeigneter Geltungsbereich wird nicht angefordert, wenn Sie sich bei Google anmelden.

Überprüfen Sie, ob die von Ihnen angeforderten Bereiche korrekt sind. Android sollte den Benutzer nach dem Authentifizierungsprozess über das Dialogfeld mit den Berechtigungsanfragen dazu auffordern, die Erlaubnis zu erteilen. Dadurch wird UserRecoverableAuthException beim Aufruf der API verhindert.

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 Benutzer hat Erlaubnis verweigert

Der Benutzer hat im Berechtigungsdialogfeld die Schaltfläche "DENY" gedrückt.

# 3 Benutzer hat Berechtigungen von Ihrer App abgelehnt.

Für Android 8.1.x gibt es ein Menü, in dem Sie Berechtigungen für einzelne Apps ablehnen können. Nicht sicher bei anderen Versionen.

Settings > Google > Connected apps

UserRecoverableAuthException, die von # 2 und # 3 ausgelöst wird, ist unvermeidbar, da diese das Ergebnis von Benutzeraktivitäten sind. Aber ist es nicht sinnlos, den Berechtigungsanforderungsdialog trotz der Ablehnung durch den Benutzer erneut mit dem folgenden Code anzuzeigen?

} catch (UserRecoverableAuthIOException e) {
  startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
}
0
Kazuyo