Search code examples
androidxamarin.androidaccountmanagerandroid-account

AccountManager: when to set result?


Context

My app only stores user/pass. No tokens are used.

Question 1

Methods setAccountAuthenticatorResult(Bundle) and onResult(Bundle) are meant to notify the AbstractAccountAuthenticator about the outcome, but I have a project working without them, what are they for ?

Question 2

What is onRequestContinued() for ?

Question 3

When addAccount is finished and the account created, should onActivityResult be called on the Activity that triggered it?

Question 4

If an Intent is returned with key AccountManager.KEY_INTENT in addAccount implementation, the AbstractAccountAuthenticator will start the Intent. I have noticed that many developers add extras. Who gets them ?

public Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options) throws NetworkErrorException
{
    Intent intent = new Intent(mContext, AuthenticatorActivity.class);
    intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);

    intent.putExtra(AuthenticatorActivity.ARG_ACCOUNT_TYPE, accountType);     // <-- this
    intent.putExtra(AuthenticatorActivity.ARG_AUTH_TYPE, authTokenType);      // <-- this
    intent.putExtra(AuthenticatorActivity.ARG_IS_ADDING_NEW_ACCOUNT, true);   // <-- this


    Bundle bundle = new Bundle();
    bundle.putParcelable(AccountManager.KEY_INTENT, intent);

    return bundle;
}

Asnwers

kris larson:

Thanks for the answer. I think we might be using the AccountManager wrong to be honest.

We want to share some credentials across our apps, so we have a Service to hold the custom account type. Since apps know the account type and share the signing certificate, they have access to the Account.

When each app is started, they try to get the Account. If no Account exists, they trigger the login page in our Service by calling AccountManager.addAccount(...).

Once the login (through web services) is successfull, we make it available to other apps with AccountManager.addAccountExplicitly(...). Not setting an outcome after it, does not impact the outcome.

How does it affect the AccountManager ? Is this approach correct ?


Solution

  • Methods setAccountAuthenticatorResult(Bundle) and onResult(Bundle) are meant to notify the AbstractAccountAuthenticator about the outcome, but I have a project working without them, what are they for ?

    Those methods (as well as onError) are to pass back a result to whoever might wait for one, e.g. have a look at AccountManager.getAuthToken(...) and many others that let you specify a AccountManagerCallback<Bundle>. This is where your result will be passed to. null is valid for the callback, so unless you structure your app around the result, it will work without it.

    AccountAuthenticatorResponse.onResult(Bundle) and onError(...) are much more important if you implement getAuthToken where this is how you can return an access token from an asynchronous backend call (e.g. token refresh).

    What is onRequestContinued() for ?

    There is very little information (reads: none) available. The only time it gets used that I could find was in AccountManagerService where it's but a counter that gets increased for logging purposes. I don't think it does anything at the moment.

    When addAccount is finished and the account created, should onActivityResult be called on the Activity that triggered it?

    Should work as long as you use startActivityForResult(..)

    If an Intent is returned with key AccountManager.KEY_INTENT in addAccount implementation, the AbstractAccountAuthenticator will start the Intent. I have noticed that many developers add extras. Who gets them ?

    As already mentioned by kris, you can return an Intent that starts your Activity and pass any extras that you might need.


    On an unrelated note: You should really try not to store any passwords in plain text. Even though the AccountManager says setPassword() it is not protected and thus not secure.