2

i'm developing an android application with accounts, sync and content provider. adding an account works, syncing also and some data is saved in the content provider.

now, when the user deletes the account using the settings, syncing stops, but the data stays in the content provider.

i'd like to delete it, but i don't know how to catch the event of account deletion.

There is AccountManager.addOnAccountsUpdatedListener(), i've tried to add it to the sync service, but the sync service is started only for the sync and then stopped. so whenever the account gets deleted while there is no sync, it can't get caught.

is there a best practice on how to handle private data when an account gets deleted?

Adam
  • 21
  • 5
  • Interesting question -- but is that really such a common event? – 323go Sep 10 '14 at 20:00
  • 1
    @323go well it always happens when you delete an account. Imagine you logging in to a messenger on a friend's device and the messages stay on it even after deleting the account. – Adam Sep 10 '14 at 23:17
  • This sounds similar to: http://stackoverflow.com/questions/6074247/custom-account-authenticator-cleanup-after-account-is-removed-from-device – nibarius Sep 11 '14 at 09:28
  • @nibarius thanks, yes it is similar. I apparently chose the wrong keywords while searching. I assume that there isn't any cleaner solution since nobody answered to the other question. – Adam Sep 11 '14 at 14:31
  • @Adam, maybe I use my devices differently from you, but I'd *never* log into a messenger on a device that isn't mine. But how would the data be available still in your `ContentProvider`? Couldn't you just verify whether the associated account exists before returning data, and then delete it? – 323go Sep 12 '14 at 05:33
  • @Adam did you find anything for this? – rupesh Aug 19 '15 at 06:24
  • No, I ended up with a workaround of always testing when necessary. But the application anyway never went into production. – Adam Aug 23 '15 at 13:40

2 Answers2

4

First You should add OnAccountsUpdateListener to you AccountManager using this command:

AccountManager mAccountMgr = AccountManager.get(getContext());
mAccountMgr.addOnAccountsUpdatedListener(new AccountsUpdateListener(), null, false);

AccountsUpdateListener is implemented class of OnAccountsUpdateListener like this:

private class AccountsUpdateListener implements OnAccountsUpdateListener {
    @Override
    public void onAccountsUpdated(Account[] accounts) {
        Account newAccount = null;
        for (final Account account : accounts) {
            if (account.type.equals(mAccountType)) {
                newAccount = account;
            }
        }

        if (newAccount == null) {
          // account removed, now you can handle your private data and remove anything you want here
        }
    }
}

onAccountsUpdated fired when you add an account or an account removed. so you can check your account type to find specified account in accounts array. if it doesn't exist it removed ! mAccountType is your account type. e.g mAccountType = "your application name"

Ali Mehrpour
  • 603
  • 8
  • 16
  • I mentioned this method in my question. The documentation says, that it should be removed again in an onDestroy method. I wouldn't want to have a service (using up ram etc) just for that.. – Adam Sep 10 '14 at 23:21
0

You should use method getAccountRemovalAllowed from your AbstactAccountAuthenticator:

    class AccountAuthenticatorImpl(context: Context) : AbstractAccountAuthenticator(context) {
    
        override fun getAccountRemovalAllowed(
            response: AccountAuthenticatorResponse?,
            account: Account?
        ): Bundle {
            val result = super.getAccountRemovalAllowed(response, account)
            val canDelete = result.getBoolean(android.accounts.AccountManager.KEY_BOOLEAN_RESULT, false)
    
            if (canDelete) {
                // TODO: account was deleted, so react on it
                accountRepository.onAccountDeletedInSystem()
            }
    
            return result
        }
    
    
    }