7

Ich habe zwei Apps, die mit demselben Kontotyp arbeiten. Ich möchte im Folgenden Seite gezeigt werden, wenn der Benutzer die zweite App für erstes Mal öffnet und ein Konto existiert:AuthToken kann nicht für ein benutzerdefiniertes Konto aus einer anderen App abgerufen werden

enter image description here

Aber nichts passiert, wenn ich diesen Code ausführen:

final AccountManagerFuture<Bundle> future = mAccountManager.getAuthToken(account, authTokenType, null, this, null, null); 

new Thread(new Runnable() { 
    @Override 
    public void run() { 
     try { 
      Bundle bnd = future.getResult(); 

      final String authtoken = bnd.getString(AccountManager.KEY_AUTHTOKEN); 
      showMessage((authtoken != null) ? "SUCCESS!\ntoken: " + authtoken : "FAIL"); 
      Log.d("udinic", "GetToken Bundle is " + bnd); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      showMessage(e.getMessage()); 
     } 
    } 
}).start(); 

Der obige Code funktioniert einwandfrei, wenn ich es von der App aus starte, die den Authentifikator hat. Wenn ich stattdessen unter Code laufe, erzeugt das System eine Benachrichtigung, dass wenn ich darauf klicke, das obige Bild erscheint.

final AccountManagerFuture<Bundle> future = mAccountManager 
     .getAuthToken(account, authTokenType, null, true, 
       null, handler); 

Durch Klicken auf die Schaltfläche "Allow" wird AuthToken korrekt zurückgegeben. Ich möchte jedoch die Berechtigungserlaubnisseite (Bild oben) sehen, wenn Sie getAuthToken aufrufen, nicht durch Klicken auf Benachrichtigung. Wie kann ich das machen?

Antwort

1

Ich benutzte diese Methode anstelle von vorherigen und jetzt sehe ich den Bestätigungsdialog:

accountManager.getAuthToken(account, AUTH_TOKEN_TYPE_FULL_ACCESS, null, true, new AccountManagerCallback<Bundle>() { 
      @Override 
      public void run(AccountManagerFuture<Bundle> future) { 
       try { 
        Bundle bundle = future.getResult(); 
        String authToken = bundle.getString(AccountManager.KEY_AUTHTOKEN); 

       } catch (OperationCanceledException | IOException | AuthenticatorException e) { 

       } 
      } 
}, null); 

Beachten Sie, dass die zweite App andere Signatur haben. Wenn beide Apps dieselbe Signatur haben, ist keine Bestätigung erforderlich und authToken wird abgerufen.

+0

Was ist der Wert von AUTH_TOKEN_TYPE_FULL_ACCESS? Ist es "Full Access", wird in meinem Fall beim erstmaligen Installieren der App dann über dem Bildschirm angezeigt, aber nachdem nichts passiert ist –

0

Ein paar Dinge, die hier zu besprechen sind. Die Verwendung eines Threads in Android wird im Allgemeinen als schlechte Praxis angesehen. Für Android-Dokumente wird empfohlen, eine Async-Aufgabe oder einen Handler zu verwenden. Jetzt für die Auth-Nachricht pro Android-Dokumentation ist die erwartete Ausgabe eine Benachrichtigung.

getAuthToken(Account account, String authTokenType, Bundle options, boolean notifyAuthFailure, AccountManagerCallback<Bundle> callback, Handler handler)

Ruft eine Auth-Token des angegebenen Typs für ein bestimmtes Konto, optional eine Benachrichtigung erhöhen, wenn die Benutzer Anmeldeinformationen eingeben müssen.

Beachten Sie, wie getAuthToken einen Handler-Parameter hat? Dies wäre die bevorzugte Methode, um die Aufgabe async zu behandeln. Das Problem ist hier you CAN NOT have a full screen message on a handler thread, because it can't interrupt the UI thread. In Ihrem ersten Beispiel rufen Sie tatsächlich Anruf mAccountManager auf dem UI-Thread, so dass es die Benutzeroberfläche übernehmen und senden Sie eine Vollbild zulassen oder verweigern Nachricht, aber dies kann nicht mit einem Handler, da ein Handler getan werden kann den UI-Thread nicht verwenden (wird zur Laufzeit einen Fehler ausgeben).

Meine vorgeschlagene Lösung? Verwenden Sie keinen Handler, wenn Sie eine unterbrechungsfreie Vollbildmeldung wünschen. Führen Sie die Aktion im UI-Thread aus, ähnlich wie bei Ihrem ersten Code-Snippet.

AccountManagerFuture<Bundle> future = mAccountManager.getAuthToken(account, authTokenType, null, this, callback, null); 
//USE implements and implement a listener in the class declaration and 
//use 'this' in the callback param OR create a new callback method for it 
+0

Versuchen Sie auch, den Rückrufparameter zu testen, damit Sie testen können, ob der Rückruf Ihnen die gesuchte Nachricht liefert. Der Rückruf ist wichtig, weil er Ihnen sagt, wann Ihr Prozess fertig ist, selbst wenn er in einem anderen Thread war. Auf diese Weise können Sie (oder das Android-System) auf der Grundlage der Ergebnisse eine UI-Eingabeaufforderung anzeigen, wie Sie es gerade versuchen. –

+0

Ich habe Ihre Lösung getestet, aber nach dem Aufruf von 'getAuthToken' ist nichts passiert. run-Methode innerhalb von Callback wird nie aufgerufen. –

+0

Ich glaube nicht, dass Sie verstehen und es gibt nicht genug Code für mich, um Ihre spezifische Situation zu testen. Um zu bekommen, was Sie wollen, müssen Sie es im UI-Thread tun. Sie können a) die gesamte Operation auf dem Benutzeroberflächenthread ausführen, dies wird wesentlich einfacher sein, oder b) einen Handler verwenden und warten, bis der Callback die Nachricht anzeigt.Ich nehme an, diese Nachricht ist eine integrierte Android-Nachricht, so dass Sie nur hoffen müssen, es wird es für Sie in den Rückruf tun, sonst stecken Sie auf dem UI-Thread fest. –