10

I just created an Account for my app.

  • The account is visible in settings
  • I set syncable="true" in my XML
  • I can perform a manual sync by pressing the settings -> onPerformSync is called
  • I can perform a "code" sync by calling ContentResolver.requestSync -> onPerformSync is called
  • And of course, yes, the sync is enabled in settings. I don't use any power saver.

I also followed all the steps from here: https://stackoverflow.com/a/5255360/327402

This is my code to get the sync by code

AccountManager am = AccountManager.get(this); 
Account[] accounts = am.getAccountsByType(ACCOUNT);
//Log.e("DEBUG", "Accounts: " + accounts.length);
if (accounts.length == 0) {
    Account account = new Account(getString(R.string.app_name), ACCOUNT);
    ContentResolver.setIsSyncable(account, AUTHORITY, 1);
    ContentResolver.addPeriodicSync(account, AUTHORITY, new Bundle(), 7200);
    ContentResolver.setSyncAutomatically(account, AUTHORITY, true);
    if (am.addAccountExplicitly(account, "pass1", null))
        Log.i("DEBUG", "account Created: " + account.name + ", " + account.type);
    else
        Log.i("DEBUG", "addAccountExplicitly returned false");
    }
else{
    ContentResolver.requestSync(accounts[0], AUTHORITY, new Bundle());// THIS IS WORKING!!!
    }
}

So, everything looks correct and fine.

But unfortunately, I cannot get a periodic sync! When I open the settings, accounts, I see the account and the date and time is the time when I performed the sync by code, or manually.

Any idea on what I did wrong, or what I forgot?

Waza_Be
  • 39,407
  • 49
  • 186
  • 260

2 Answers2

2

Rewrite

I have put together a sample project on GitHub that demonstrates a working SyncAdapter. The project is here.

I have only tried this on an emulator with API 17 since I didn't want to wait around an hour or so (maybe longer now) for a sync to happen. I would suggest that you take this route as well.

On API 17, this demo will do a sync every 30 seconds or so. Everything runs out of the main activity with stub support classes: SyncAdapter, StubProvider, etc. The only thing the sync adapter does is to log a message to logcat that it has run.

I don't really see anything wrong with your code other than, perhaps, the order of the calls to set up the sync is incorrect. Take a look at the call order in the demo for an example of what works.

I hope you find this useful.

(I did this on Android Studio 3.0 Canary 5. I hope this is not an issue.)

Cheticamp
  • 61,413
  • 10
  • 78
  • 131
  • 1
    I had to add something here as I'd been scratching my head for a day or so before digging around in AOSP codebase. Pre-API 24 the minimum sync frequency is 60 seconds, it will always round this up. You can see this from the logs (Requested poll frequency of " + runAtTime + " seconds being rounded up to 60 seconds.) or by looking at the syncs returned by ContentResolver.getPeriodicSyncs(account, CONTENT_AUTHORITY); Post-API 24 the minimum sync period is now 15 minutes. So all values below this will be rounded up to 15 minutes. – WillEllis Nov 19 '17 at 21:42
0

One important thing to remember is that the periodic sync time is not guaranteed and may not be accurate, this is mentioned in the documentation:

Although these sync are scheduled at the specified frequency, it may take longer for it to actually be started if other syncs are ahead of it in the sync operation queue. This means that the actual start time may drift.

I would also try to create the account using AccountManager and not by creating new Account()

 manager.addAccountExplicitly(account, null, null)

And last thing, if this account was just created than you may want to force only the first sync right after you set the automatic sync settings:

 if (accountJustCreated) { 
   SyncAdapter.performSync();
 }
ApriOri
  • 2,618
  • 29
  • 48
  • 2
    Your last tip is what I did and work fine, but the periodic part is not wiorking at all despite ContentResolver.addPeriodicSync(account, AUTHORITY, new Bundle(), 7200); – Waza_Be Jul 06 '17 at 14:32