2014-10-01 7 views
5

alle.Asynchrone Kontoauthentifizierung mit Volley

Ich bin ein Konto Authenticator mit AbstractAccountAuthenticator implementieren und ich muss eine asynchrone Methode in der Funktion getAuthToken aufrufen, um einen Benutzer zu authentifizieren. Mein Code ist wie folgt:

public class AccountAuthenticator extends AbstractAccountAuthenticator { 
    ... 
    @Override 
    public Bundle getAuthToken(final AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) 
     throws NetworkErrorException 
    { 
     final AccountManager accountManager = AccountManager.get(context); 
     String authToken = accountManager.peekAuthToken(account, authTokenType); 
     // !!!! 
     if(TextUtils.isEmpty(authToken)) { 
      <<call asynchronous method to acquire token>> 
      return null; 
     } 
     // !!!! 
     final Bundle result = new Bundle(); 
     result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); 
     result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type); 
     result.putString(AccountManager.KEY_AUTHTOKEN, authToken); 
     return result; 
    } 
    ... 
} 

Laut Google in der Dokumentation für die ‚getAuthToken‘ Methode: es gibt ein Bündel Ergebnis oder null, wenn das Ergebnis über die Reaktion zurückgeführt werden soll. Das Ergebnis enthält entweder:
AccountManager.KEY_INTENT oder
AccountManager.KEY_ACCOUNT_NAME, AccountManager.KEY_ACCOUNT_TYPE und AccountManager.KEY_AUTHTOKEN oder
AccountManager.KEY_ERROR_CODE und AccountManager.KEY_ERROR_MESSAGE einen Fehler

, um anzuzeigen, Und ich brauche null zurück, weil die Authenticator Methode ist asynchron, aber wie gebe ich das Bundle über den Parameter 'response' gemäß der Dokumentation zurück?
Danke für alle, und Entschuldigung mein Englisch.

Antwort

5

Ja, ich habe die Lösung gefunden. Sie müssen den Parameter 'response' verwenden, um die Ergebnisse zurückzugeben. Unten ist die Quelle, die ich in meiner Anwendung verwende. Ich hoffe, das kann helfen.

 


    public Bundle getAuthToken(final AccountAuthenticatorResponse response, final Account account, String authTokenType, Bundle options) 
    throws NetworkErrorException 
    { 
     final Bundle result = new Bundle(); 
     // We will not allow authentication for a type of account not used by the service. 
     if(false == authTokenType.equals(Accounts.TokenTypes.User)) { 
      result.putString(AccountManager.KEY_ERROR_MESSAGE, context.getString(R.string.error_invalid_auth_token_type)); 
      return result; 
     } 

     final AccountManager accountManager = AccountManager.get(context); 
     String authToken = accountManager.peekAuthToken(account, authTokenType); 
     Token token = null; 
     // If the account already has an authorization key ... 
     if(! TextUtils.isEmpty(authToken)) 
     { 
      // ...load its details from the userdata's account. 
      String tokenStr = accountManager.getUserData(account, Token.class.getName()); 
      JSONObject tokenJson = null; 
      try { 
       tokenJson = new JSONObject(tokenStr); 
       token = new Token(tokenJson); 
      } 
      catch(JSONException e) { 
       token = new Token(); 
      } 
     } 
     // But if the key is invalid or expired ... 
     if(token == null || token.isExpired()) 
     { 
      // ...loads the account user credentials to try to authenticate it. 
      new SignInRequest(new Client(), account.name, accountManager.getPassword(account), 
       new Response.Listener() { 
        @Override 
        public void onResponse(Token token) { 
         /* 
         Response: a Bundle result or null if the result is to be returned via the response. 
         The result will contain either: 
         • AccountManager.KEY_INTENT (!!qdo envia o bundle para uma atividade!!), or 
         • AccountManager.KEY_ACCOUNT_NAME, AccountManager.KEY_ACCOUNT_TYPE, and AccountManager.KEY_AUTHTOKEN, or 
         • AccountManager.KEY_ERROR_CODE and AccountManager.KEY_ERROR_MESSAGE to indicate an error 
         */ 
         result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); 
         result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type); 
         result.putString(AccountManager.KEY_AUTHTOKEN, token.getAccessToken()); 
         response.onResult(result); 
        } 
       } 
       , 
       new Response.ErrorListener() { 
        @Override 
        public void onErrorResponse(VolleyError volleyError) { 
         int errorCode = (volleyError.networkResponse == null ? -1 : volleyError.networkResponse.statusCode); 
         String errorMessage = null; 
         if(volleyError.getLocalizedMessage() != null) 
          errorMessage = volleyError.getLocalizedMessage(); 
         else if(volleyError.getMessage() != null) 
          errorMessage = volleyError.getMessage(); 
         else 
          errorMessage = volleyError.toString(); 
         result.putInt(AccountManager.KEY_ERROR_CODE, errorCode); 
         result.putString(AccountManager.KEY_ERROR_MESSAGE, errorMessage); 
         response.onError(errorCode, errorMessage); 
        } 
       } 
      ).execute(this.context); 
      // Returns null because we use the response parameter. See callbacks above. 
      return null; 
     } 
     // Otherwise, the key is valid, it returns. 
     result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); 
     result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type); 
     result.putString(AccountManager.KEY_AUTHTOKEN, authToken); 
     return result; 
    } 

 
+0

danke, aber zurück Null und OnResponse laufen über verschiedene Threads !!!! – SanatiSharif

+0

@SanatiSharif Kein Problem! Das Argument "Antwort" ist der Typ von dir, der deine Antwort zurückgibt. Es wird wirklich dafür verwendet, wenn Ihre Methode nicht sofort zurückkehren kann. Siehe zum Beispiel die Zeilen: 'response.onResult (result)'; und 'response.onError (result);' – Luciano