Volley的异步账号认证
问题描述:
everyone。Volley的异步账号认证
我正在使用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;
}
...
}
根据谷歌的文档,以“getAuthToken”的方法: 它返回一个Bundle结果或NULL,如果结果是通过响应归还。 结果将包含两种:0 •AccountManager.KEY_INTENT
,或
•AccountManager.KEY_ACCOUNT_NAME
,AccountManager.KEY_ACCOUNT_TYPE
和AccountManager.KEY_AUTHTOKEN
,或
•AccountManager.KEY_ERROR_CODE
和AccountManager.KEY_ERROR_MESSAGE
指示错误
,我需要返回null,因为认证方法是异步的,但根据文档,我是如何通过'response'参数返回Bundle的?
谢谢大家,对不起我的英语。
答
是的,我找到了解决方案。您必须使用'响应'参数来返回结果。以下是我在应用程序中使用的源代码。 我希望这可以帮助。
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;
}
谢谢,但返回null和OnResponse运行在不同的线程!!!! – SanatiSharif 2015-02-28 20:24:14
@SanatiSharif没问题! “回应”这个论点是你的家伙会退回你的respost。当你的方法不能立即返回的时候,它真的用于这个。例如,请参阅行:'response.onResult(result)';和'response.onError(result);' – Luciano 2015-10-19 18:12:44