Disallow multiple accounts in AccountManager
Asked Answered
S

3

12

I've implemented my AccountManager authenticator and the service and the whole deal and it all seems to be working fine.

There is, however, one little problem: I only want a single account for my app to exist in account manager, but can't quite seem to find a way to limit this.

Is my only solution to do a search and delete the current accounts (by type) before adding the new account?

My current code:

private void removeAccounts()
{
    Account [] accounts = mAcctMgr.getAccountsByType (mAccountType);

    if (accounts.length == 0) return;

    final Handler handler = new Handler (); 

    AccountManagerCallback<Boolean> callback = new AccountManagerCallback<Boolean>()
    {
        @Override
        public void run(AccountManagerFuture<Boolean> arg0)
        {
           // nada
        }
    };

    for (Account a : accounts) {
        mAcctMgr.removeAccount (a, callback, handler);
    }
}

I don't by any means call this an elegant solution, but at the moment seems to be the only thing that works.

Scottiescottish answered 12/1, 2012 at 8:34 Comment(6)
What speaks against searching the accounts and delete or override if there already exists oneGosse
Because if there is a way to limit the accounts to a single one, then that would obviously be the proper way of doing it. Have you done this? I can't override an account, once you load an account the fields are final. Deleting is asynchronous and uses an interface which isn't at all documented. Leaving the interface method blank seems to work, but for obvious reasons I don't want to do that.Scottiescottish
I already used AccountManager and I don't know any other way to limit the accounts to a single one. I think you should prompt the user with a dialog if he wants to remove the old one and then let him create a new one. I don't think there is a more elegant way to do that.Gosse
Well ... it seems to work for now. I'll have to put in some processing code in the 'run' method to log the user out of the server. Thanks for the response.Scottiescottish
I have a question related to this, Can my account which i have created in account manager survive a uninstall, means even though user have uninstalled the app, i still want account manager to be there in order to use it when user install application againArelus
@Arelus It won't survive an uninstall and it shouldn't IMO ... Imagine if every app you ever uninstalled left something on the device.Scottiescottish
K
14

Per the javadocs for addAccount(), if an error condition occurs when creating the account, you should return a bundle that contains the KEY_ERROR_CODE and KEY_ERROR_MESSAGE parameters,

    if (accountExists) {
        final Bundle result = new Bundle();
        result.putInt(AccountManager.KEY_ERROR_CODE, ERROR_CODE_ONE_ACCOUNT_ALLOWED);
        result.putString(AccountManager.KEY_ERROR_MESSAGE, context.getString(R.string.one_account_allowed));

        handler.post(new Runnable() {

            @Override
            public void run() {
                RepeatSafeToast.show(context, R.string.one_account_allowed);
            }
        });
        return result;
    }

Returning null does not mean failure, it means that the result will be communicated through the response parameter to the addAccount() method.

Keefer answered 11/12, 2012 at 21:31 Comment(2)
How the heck do I resolve for accountExists? I don't know how to detect if a particular Account Type exist in the Android Account Manager.Seasonal
"How the heck do I resolve for accountExists?" accountManager.getAccountsByType(yourType).length; And you should know your app Account type.Sigmon
P
5

In the addAccount function of your Authenticator class (the one which extends AbstractAccountAuthenticator), first check if an account exists. If an account already exists, just return null (And maybe show a toast message). If there are no accounts, just return the bundle like you were doing before.

        if(AccountHelper.accountExists(mContext)) {
        mHandler.post(new Runnable() {

            @Override
            public void run() {
                Toast.makeText(mContext, "Only one account allowed", Toast.LENGTH_SHORT).show();
            }
        });
        return null;
    }
Plethoric answered 7/3, 2012 at 22:48 Comment(2)
Returning null on addAccount : "null if the result is to be returned via the response" . You can shoot the Toast message but should return a Bundle with : "KEY_ERROR_CODE and KEY_ERROR_MESSAGE to indicate an error" . AbstractAccountAuthenticatorEau
How do I check if an account exists?Seasonal
T
0

That link says how rename an account, which may be equivalent to your request renameAccount on developer.Android. However it is only available from API-level 21. If somebody gets a way to make it for earlier devices, please share!

Tyne answered 10/1, 2015 at 6:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.