Android AccountManager.getUserData() returns null
Asked Answered
N

3

4

I have a similar problem like this AccountManager getUserData returning null despite it being set But the solutions did not work for me

My Authenticator.java

public class Authenticator extends AbstractAccountAuthenticator{

    private Context context;
    public Authenticator(Context context) {
        super(context);
        this.context = context;
    }

    @Override
    public Bundle editProperties(AccountAuthenticatorResponse response,
            String accountType) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Bundle addAccount(AccountAuthenticatorResponse response,
            String accountType, String authTokenType,
            String[] requiredFeatures, Bundle options)
            throws NetworkErrorException {
        Bundle result = new Bundle();
        Intent intent = new Intent(context,LoginActivity.class);
        intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, accountType);
        intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
        result.putParcelable(AccountManager.KEY_INTENT, intent);
        return result;
    }

    @Override
    public Bundle confirmCredentials(AccountAuthenticatorResponse response,
            Account account, Bundle options) throws NetworkErrorException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Bundle getAuthToken(AccountAuthenticatorResponse response,
            Account account, String authTokenType, Bundle options)
            throws NetworkErrorException {

        return null;
    }

    @Override
    public String getAuthTokenLabel(String authTokenType) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Bundle updateCredentials(AccountAuthenticatorResponse response,
            Account account, String authTokenType, Bundle options)
            throws NetworkErrorException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Bundle hasFeatures(AccountAuthenticatorResponse response,
            Account account, String[] features) throws NetworkErrorException {

        return null;
    }

}

I added an account like this

mAccount = new Account("SalesGenie", "com.ambertag.salesgenie.ACCOUNT"); 
mAccountManager.addAccountExplicitly(mAccount, password, userData);

But when I try to get user data by calling getUserData() I get null

Niko answered 24/2, 2015 at 9:13 Comment(0)
I
11

There is a much simpler solution:

Don't add the user-data with addAccountExplicitly(Account, String, Bundle). Instead, just pass an empty bundle and use setUserData(Account, String, String) to add the user-data after you created the account with addAccountExplicitly.

It may be a little less convenient, but it will make sure that the user-data cache is populated properly and won't return null.

Ierna answered 21/4, 2015 at 15:11 Comment(1)
Thank you for reply.. By know I have figured out all those things,+1 for information about setUserData(Account, String, String)Niko
F
1

After some testing I've found these issues.

  • The problem only occurs on the account created after an account was manually deleted through accounts in Settings.
  • Restarting the device or reinstalling the app fixes the issue (until the first point happens again).
  • So far I have only seen the issue on a HTC

The solution:

Call the below method in addAccount() of your Authenticator.

/**
 * This method is a hack to fix a bug that is found on HTC devices.
 *
 * The issue is basically when ever an account is manually deleted through the devices
 * settings the user data that is saved in the next account that is created is not accessible.
 * The solution is to create a temp account and delete it from the app instead. Deleting
 * accounts via the AccountManager gets around the bug.
 */
private void htcAccountSyncHack() {
    Context appContext = [Application].getInstance();
    Account account = new Account([accountName], [accountType]);
    AccountManager accountManager = (AccountManager) appContext.getSystemService(
            Context.ACCOUNT_SERVICE);
    accountManager.addAccountExplicitly(account, null, null);
    accountManager.removeAccount(account, null, null);
    SharedprefsMgr.setBooleanOnSessionSets(SharedprefsMgr.ACCOUNT_MANUALLY_DELETED, false);
}

Ideally you will have a ContentProvider that is registered as a OnAccountsUpdateListener in AccountManager. You can then use this to work out if the account was manually deleted or not. If it wasn't there is no need to call this method every time.

Finkle answered 31/3, 2015 at 0:31 Comment(0)
C
0

Marten's answer did not resolve this in our app. The documentation says "It is safe to call this method from the main thread" and our app was calling AccountManager.getUserData() on a background thread, which usually worked fine, but apparently isn't guaranteed to work.

Czernowitz answered 15/12, 2019 at 0:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.