Custom Account authenticator. Cleanup after account is removed from device
Asked Answered
B

2

19

Is there a way to get some kind of notification/broadcast/etc. when a custom account is removed from "Accounts & sync settings"?

The application I have can facilitate multiple users on a device (this is for a corporate use) and uses a single SQLite database. Say I create multiple users for my application on a device and populate database with data that is relevant only to those two users. My problem here is that if one of the user is removed from "Accounts & sync settings" I have no way to cleanup database and/or some external files on SD card.

I could duplicate user information in a redundant table and compare it with registered accounts and then removing user data from the database if user information in the table and Account[] array from AccountManager does not match. Feels dirty to me.

Bradlybradman answered 20/5, 2011 at 15:35 Comment(2)
what about getAccountRemovalAllowed in your Authenticator class that is extending AbstractAccountAuthenticator? like selvinlistsyncsample.codeplex.com/SourceControl/changeset/view/…Worthy
That works better than the accepted answer...thanksMarshall
H
13

You have two options:

  1. You can use the addOnAccountsUpdatedListener method of AccountManager to add a listener in the onCreate method of an Activity or Service -- make sure you remove the listener in your onDestroy method (i.e. do NOT use this in an endlessly running service) or the Context used to retrieve the AccountManager will never be garbage collected

  2. The AccountsService will broadcast an intent with the action AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION every time an account is added, removed or changed which you can add a receiver for.

Halt answered 20/5, 2011 at 18:16 Comment(4)
Pity it doesn't supply removed account info, but it is possible to work around that. Thanks!Bradlybradman
Yes it just gives you the list of the current accounts.Halt
Third option which provides the Account: #11215289Speight
2. option is now deprecated from API 26: developer.android.com/reference/android/accounts/…Climatology
W
3

I didn't see a lot of examples on how people implement account cleanup, so I thought I would post my solution (really a variation of the accepted answer).

public class AccountAuthenticatorService extends Service {
    private AccountManager _accountManager;
    private Account[] _currentAccounts;
    private OnAccountsUpdateListener _accountsUpdateListener = new OnAccountsUpdateListener() {
        @Override
        public void onAccountsUpdated(Account[] accounts) {

            // NOTE: this is every account on the device (you may want to filter by type)
            if(_currentAccounts == null){
                _currentAccounts = accounts;
                return;
            }

            for(Account currentAccount : _currentAccounts) {
                boolean accountExists = false;
                for (Account account : accounts) {
                    if(account.equals(currentAccount)){
                        accountExists = true;
                        break;
                    }
                }

                if(!accountExists){
                    // Take actions to clean up.  Maybe send intent on Local Broadcast reciever
                }
            }
        }
    };

    public AccountAuthenticatorService() {

    }

    @Override
    public void onCreate() {
        super.onCreate();
        _accountManager = AccountManager.get(this);

        // set to true so we get the current list of accounts right away.
        _accountManager.addOnAccountsUpdatedListener(_accountsUpdateListener, new Handler(), true);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
       _accountManager.removeOnAccountsUpdatedListener(_accountsUpdateListener);
    }

    @Override
    public IBinder onBind(Intent intent) {
        AccountAuthenticator authenticator = new AccountAuthenticator(this);
        return authenticator.getIBinder();
    }
}
Webbing answered 14/4, 2016 at 13:57 Comment(3)
I've implemented this, but never gets hit. I add an account explicitly then go and remove it from accounts. Doesn't get hit at all. Even if I remove other accountsIbo
Assuming everything with the Service has been setup it could be that the API is a little different? Have you tried using the API level 26 version that takes account types?Webbing
Another option might be to wrap the OnAccountsUpdateListener listener in livedata. onActive, call addOnAccountsUpdatedListener and onInactive call removeOnAccountsUpdatedListener. Then observe the livedataBurgomaster

© 2022 - 2024 — McMap. All rights reserved.