ContentResolver.addPeriodicSync interval round up

2019-01-20 01:02发布

问题:

My sync adapter does work perfectly well except for one little thing which bugs the sh*t out of me for the last few hours... For my app i want the sync adapter to run with an interval of 10 seconds.

ContentResolver.addPeriodicSync(mAccount, AUTHORITY, Bundle.EMPTY, 5);

What happens is that the sync starts every 60 seconds instead of the requested 5 seconds. When i change the interval to 70 seconds then the sync starts every 70 seconds.

From the log file:

W/ContentService﹕ Requested poll frequency of 5 seconds being rounded up to 60 seconds.

Or, to be sure that the ContentService is taking about my interval, when i change the interval to 13 seconds:

W/ContentService﹕ Requested poll frequency of 13 seconds being rounded up to 60 seconds.

Does someone has any knowledge about the reason of this round up ?

Happens on my Motorola XT with Android 5.0.2 (Api level 22).

Tried it with the emulator, Android 4.0.4 (Api level 15), and it does the same thing only without the log message and instead of 60 seconds the interval is changed to 30 seconds. So there must be some limitation i am not aware of.

Thanks, let me know if more information is required.

回答1:

It seems to be that it is not possible to add a period sync with an interval lesser than 60 seconds. (Or least from 4.4 and higher.)

https://android.googlesource.com/platform/frameworks/base/+/kitkat-mr1-release/services/java/com/android/server/content/ContentService.java

if (request.isPeriodic()) {
    mContext.enforceCallingOrSelfPermission(
        Manifest.permission.WRITE_SYNC_SETTINGS,
        "no permission to write the sync settings");
    if (runAtTime < 60) {
        Slog.w(TAG, "Requested poll frequency of " + runAtTime
            + " seconds being rounded up to 60 seconds.");
        runAtTime = 60;
    }
    PeriodicSync syncToAdd =
        new PeriodicSync(account, provider, extras, runAtTime, flextime);
    getSyncManager().getSyncStorageEngine().addPeriodicSync(syncToAdd, userId);
}


回答2:

W/ContentService: Requested poll frequency of 300 seconds being rounded up to 900s.

It seems that on Android 7 and 8 the minimum frequency is 15 min. Till Android 6 we had a round up to 60 sec, which is decent.

I also noticed that we have a note on pollFrequency that 1h is minimum.

pollFrequency long: the amount of time in seconds... A minimum period of 1 hour is enforced.

It seems pretty inconsistent to me.



回答3:

The problem here is the wrong documentation in the android source code.

The real values are:

  • Starting with Froyo (API 8) which first introduced addPeriodicSync method, there wasn't a minimum time interval, source here and here (even if internally each retry has to wait a minimum of 30 seconds).
  • Starting with KitKat (API 19) the minumum interval has been set to 1 minute, source here
  • Starting from Nougat (API 24) the minimum interval is 15 minutes, source here, here and here

Additional info:

  • Starting from Marshmallow (API 23), the periodic sync frequency it's also affected by doze mode and additional OS battery optimizations

PS: The documentation of addPeriodicSync(...) is wrong about pollFrequency param before API 24, I've opened an issue waiting Google to fix it.