【问题标题】:Asynchronous account authentication with Volley使用 Volley 进行异步帐户身份验证
【发布时间】:2014-11-26 07:32:14
【问题描述】:

大家。

我正在使用 AbstractAccountAuthenticator 实现一个帐户身份验证器,我需要在函数 getAuthToken 中调用一个异步方法来对用户进行身份验证。 我的代码是这样的:

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;
    }
    ...
}

根据 Google 的“getAuthToken”方法文档: 如果要通过响应返回结果,则返回 Bundle 结果或 null。 结果将包含:
AccountManager.KEY_INTENT,或
AccountManager.KEY_ACCOUNT_NAMEAccountManager.KEY_ACCOUNT_TYPEAccountManager.KEY_AUTHTOKEN,或
AccountManager.KEY_ERROR_CODEAccountManager.KEY_ERROR_MESSAGE 表示错误

而且我需要返回 null,因为身份验证器方法是异步的,但是根据文档,我如何通过 'response' 参数返回 Bundle?
谢谢大家,对不起我的英语。

【问题讨论】:

    标签: android asynchronous token android-volley accountmanager


    【解决方案1】:

    是的,我找到了解决方案。您必须使用 'response' 参数来返回结果。下面是我在我的应用程序中使用的源代码。 我希望这会有所帮助。

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

    【讨论】:

    • @SanatiSharif 没问题!参数“响应”是您将返回您的回复的人。当您的方法无法立即返回时,它确实用于此目的。例如,请参阅以下行:response.onResult(result);和response.onError(result);
    猜你喜欢
    • 1970-01-01
    • 2021-02-08
    • 2018-09-01
    • 2016-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-04
    相关资源
    最近更新 更多