everybody.
I'm implementing an account authenticator using AbstractAccountAuthenticator and I need call an asynchronous method in the function getAuthToken, to authenticate a user. My code is like this:
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;
}
...
}
According to Google's documentation for the 'getAuthToken' method:
it returns a Bundle result or null if the result is to be returned via the response.
The result will contain either:
• AccountManager.KEY_INTENT
, 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
And I need to return null because the authenticator method is asynchronous, but how I return the Bundle via the 'response' parameter, according to the documentation?
Thanks for all, and sorry my english.
Yes, I found the solution. You must use the 'response' parameter to return the results. Below is the source that I use in my application. I hope this can help.
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With