Custom Account authenticator. Cleanup after account is removed from device
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 u开发者_如何学编程se) 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.
You have two options:
You can use the
addOnAccountsUpdatedListener
method ofAccountManager
to add a listener in theonCreate
method of anActivity
orService
-- make sure you remove the listener in youronDestroy
method (i.e. do NOT use this in an endlessly running service) or theContext
used to retrieve theAccountManager
will never be garbage collectedThe
AccountsService
will broadcast an intent with the actionAccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION
every time an account is added, removed or changed which you can add a receiver for.
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();
}
}
精彩评论