Search code examples
androidsynchronizationaccounts

SyncAdapter not being called depending on order of Account setup calls


I've come across some slightly odd behaviour with my SyncAdapter.

The first time I install my app (after uninstalling with adb), it launches and creates an account. Depending on the ordering of some statements (see below), my SyncAdapter's onPerformSync() will never be called; my account under "Accounts and sync" shows the "sync in progress" icon spinning indefinitely. If I then uncheck the sync checkbox next to my app's account, and then recheck it, my onPerformSync() is called immediately.

This causes my SyncAdapter to never be called. "sync in progress" icon spins forever, unless I uncheck, then recheck the sync checkbox:

final Account account = new Account(mUsername, getString(R.string.ACCOUNT_TYPE));
mAccountManager.addAccountExplicitly(account, mPassword, null);
ContentResolver.setSyncAutomatically(account, getString(R.string.CONTENT_AUTHORITY), true);
ContentResolver.setIsSyncable(account, getString(R.string.CONTENT_AUTHORITY), 1);

With this ordering of the same statements, everything works perfectly:

final Account account = new Account(mUsername, getString(R.string.ACCOUNT_TYPE));
ContentResolver.setSyncAutomatically(account, getString(R.string.CONTENT_AUTHORITY), true);
ContentResolver.setIsSyncable(account, getString(R.string.CONTENT_AUTHORITY), 1);
mAccountManager.addAccountExplicitly(account, mPassword, null);

My guess is I'm putting the SyncManager into some inconsistent state due to it firing off a sync request instantly on account creation, and I'm changing its config under its feet. But the (barely coherent) documentation doesn't mention any issues with calling these functions whenever you like.

As an aside for others struggling with SyncAdapters, I found that contentResolver.requestSync() will never trigger your SyncAdapter.onPerformSync() unless you call ContentResolver.setIsSyncable(account, getString(R.string.CONTENT_AUTHORITY), 1);.

Could someone explain this behaviour? The documentation surrounding Accounts and Syncing is somewhat unclear to say the least.

I'm getting this behaviour on the 2.1 Emulator, compiling against the 2.1 SDK.


Solution

  • I found that contentResolver.requestSync() will never trigger your SyncAdapter.onPerformSync() unless you call ContentResolver.setIsSyncable(account, getString(R.string.CONTENT_AUTHORITY), 1);.

    For a detailed account of the solution I went with using SyncAdapter, see my answer here:

    https://stackoverflow.com/a/12015967/988870