Search code examples
androidandroid-syncadapter

Periodic Sync never triggering


Im using SyncAdapter for some server client synchronization. In the official android developer guide it is mentioned that there are different methods to trigger a sync.

1 Run the Sync Adapter When Server Data Changes

You simply call:

ContentResolver.requestSync(ACCOUNT, AUTHORITY, null);

When server data changes (on GCM for example).

2 Run the Sync Adapter When Content Provider Data Changes

Simply use a ContentObserver

public class TableObserver extends ContentObserver {
    @Override
    public void onChange(boolean selfChange) {
        onChange(selfChange, null);
    }

    @Override
    public void onChange(boolean selfChange, Uri changeUri) {
        ContentResolver.requestSync(ACCOUNT, AUTHORITY, null);
    }
}

3 Run the Sync Adapter After a Network Message

Do the following:

ContentResolver.setSyncAutomatically(ACCOUNT, AUTHORITY, true)

Now everytime when there is an open TCP/IP connection the SyncAdapter is triggered to perform the sync.

4 Run the Sync Adapter Periodically

This is for me the important and interesting part. For that you simply have to do this (at least this is written in the developers guide):

public static final long SECONDS_PER_MINUTE = 60L;
public static final long SYNC_INTERVAL_IN_MINUTES = 60L;
public static final long SYNC_INTERVAL = SYNC_INTERVAL_IN_MINUTES * SECONDS_PER_MINUTE;

ContentResolver.addPeriodicSync(
            ACCOUNT,
            AUTHORITY,
            Bundle.EMPTY,
            SYNC_INTERVAL);

Now to the problem

Solution 1, 2 and 3 are working perfectly as they should. The periodical sync does not. If i just do what is descriped under point 4 the synchronization is never triggered (yes i did enable the auomatic synchronisation in the system settings of my android device).

If i do the following:

ContentResolver.setIsSyncable(account, ContentProviderMeasure.AUTHORITY, 1);
ContentResolver.setSyncAutomatically(account, ContentProviderMeasure.AUTHORITY, true);
ContentResolver.addPeriodicSync(account, ContentProviderMeasure.AUTHORITY, new Bundle(), 3600);

The SyncAdapter sync refresh is called every minute (it should be every hour / 3600 seconds = 1 hour). If i do the following:

ContentResolver.setIsSyncable(account, ContentProviderMeasure.AUTHORITY, 1);
ContentResolver.addPeriodicSync(account, ContentProviderMeasure.AUTHORITY, new Bundle(), 3600);

The sync is only triggered once at creation time and after that never again. Yes, as i mentioned already, the automatic sync in the android devices settings is enabled.

Triggering the sync manually for my app in the android device settings accountmanager is working fine.

So why does the periodic sync does not work?

I tested on Nexus 4 with Android 6.0, On Galaxy Ace with Android 4.4 and on Galaxy S3 Mini with Android 4.1. All devices are not syncing periodically.


Solution

  • I have implemented Periodic Sync for Calendar AUTHORITY.

    Add <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" /> permission in Manifest file.

    Add below method for Sync:

    public void syncAllAccountsPeriodically(Context contextAct, long seconds) throws Exception {
        AccountManager manager = AccountManager.get(contextAct);
        Account[] accounts = manager.getAccountsByType("com.google");
        String accountName = "";
        String accountType = "";
        for (Account account : accounts) {
            accountName = account.name;
            accountType = account.type;
            break;
        }
    
        Account a = new Account(accountName, accountType);
        ContentResolver.addPeriodicSync(a, "com.android.calendar", new Bundle(), seconds*1000);
    }
    

    I hope this would help you.