简体   繁体   中英

How to remove account in AccountManager in Android

I am trying to remove a custom account in AccountManager.

This is my code :

final Handler handler = new Handler (); 

AccountManagerCallback<Boolean> callback = new AccountManagerCallback<Boolean>()
        {
            @Override
            public void run(AccountManagerFuture<Boolean> arg0)
            {
                String test = "test";
            }
        };

AccountManagerFuture<Boolean> bool = am.removeAccount(account, callback, handler);

Permissions I'm using :

<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS"></uses-permission> 
<uses-permission android:name="android.permission.GET_ACCOUNTS"></uses-permission> 
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"></uses-permission>
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS"></uses-permission>

The account is never removed and the callback never called, any idea ? No trace in logs

Try this it will work

    // Global Variables 
    public static final String AUTHORITY = "com.example.package";
    public static final String ACCOUNT_TYPE = "com.example.package";
    public static final String ACCOUNT = "my_custom_account_name";

    // Account Manager definition
    AccountManager accountManager = (AccountManager) this.getSystemService(ACCOUNT_SERVICE);

    // loop through all accounts to remove them
    Account[] accounts = accountManager.getAccounts();
    for (int index = 0; index < accounts.length; index++) {
    if (accounts[index].type.intern() == AUTHORITY)
        accountManager.removeAccount(accounts[index], null, null);
    }

requires

<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />

You need to override the following method in the Authenticator class from AbstractAccountAuthenticator .

public Bundle getAccountRemovalAllowed(AccountAuthenticatorResponse response, Account account) {
    Bundle result = new Bundle();
    boolean allowed = true; // or whatever logic you want here
    result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, allowed);
    return result;
}

Had the same problem

if (VERSION.SDK_INT < VERSION_CODES.LOLLIPOP_MR1) {
            accountManager.removeAccount(account, {}, AContext.app.mainHandler)
        } else {
            accountManager.removeAccountExplicitly(account)
        }

For API 22 and higher works perfectly, but on API 19 didn't work at all.

Finally found the problem in my implementation of AbstractAccountAuthenticator:

override fun getAccountRemovalAllowed(response: AccountAuthenticatorResponse?, account: Account?): Bundle {
    AccountHelper.removeAccount()
    return super.getAccountRemovalAllowed(response, account)
}

It became to work after deleting "AccountHelper.removeAccount()"

I don't know - maybe it'll help

You have to call 2 below methods before removeAccount method and the system will allow you to remove the account in account manager. clearPassword invalidateAuthToken

Based on the description on the removeAccount method:

"The authenticator may have its own policies preventing account deletion, in which case the account will not be deleted."

Have fun.

This Code works like a charm to me.

You will need the WRITE_SYNC_SETTINGS,also need to add android.permission.MANAGE_ACCOUNTS works for me with same code pattern. permission. So if you use AccountManager and Account correctly you will manage to remove the account successfully.

I had some issues using the account manager in the Android Simulator, so try to test on a real device...

AccountManager accMgr = AccountManager.get(this);
final Account account = new Account(username, accountType);

removeCaxtonAccount(accMgr, account);

public void removeCaxtonAccount(AccountManager accMgr, Account account){
        accMgr.removeAccount(account, null,null);
    }

Here is my solution. The previous solutions I found don't explicitly wait for the removal of accounts to finish so they randomly fail.

    final AccountManager accountManager = AccountManager.get(getContext());
    final String accountType = AuthenticatorService.ACCOUNT_TYPE;

    final Account[] availableAccounts = accountManager.getAccountsByType(accountType);
    for (final Account availableAccount : availableAccounts) {
        final AccountManagerFuture<Boolean> booleanAccountManagerFuture = accountManager.removeAccount(availableAccount, null, null);
        assertTrue("Impossible to delete existing account for this application", booleanAccountManagerFuture.getResult(1, TimeUnit.SECONDS));
    }

Note: You still need the permissions mentioned before.

I my case for api before 22 adding Authenticator class helped. Just inspire yourself from this source https://www.programcreek.com/java-api-examples/?code=MLNO/airgram/airgram-master/TMessagesProj/src/main/java/ir/hamzad/telegram/ContactsController.java#

for api 22+ this works without Authenticator : if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { Timber.e(String.valueOf(accountManager.removeAccountExplicitly(account))); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { Timber.e(String.valueOf(accountManager.removeAccountExplicitly(account))); }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM