Reputation: 2077
I need to connect the system server for each 1 minute from my mobile app to sync data. For that I am using SyncAdapter
class in my app. It works fine for mobiles having api < 23 (upto marshmallow it works fine). When I test my app in mobile having api > 23 , the sync adapter class not firing. It fires only the first time I install the app in the device.
I am using the following code in my app. Can anyone help me to solve the problem?
public class MyServiceSyncAdapter extends AbstractThreadedSyncAdapter {
//TODO change this constant SYNC_INTERVAL to change the sync frequency
public static final int SYNC_INTERVAL = 20; //60 * 180; // 60 seconds (1 minute) * 180 = 3 hours
public static final int SYNC_FLEXTIME = SYNC_INTERVAL/3;
private static final int MOVIE_NOTIFICATION_ID = 3004;
public static DataBaseConnection mCon;
public MyServiceSyncAdapter(Context context, boolean autoInitialize) {
super(context, autoInitialize);
mCon = new DataBaseConnection(this.getContext());
}
@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
Log.i("MyServiceSyncAdapter", "onPerformSync");
//TODO get some data from the internet, api calls, etc.
//TODO save the data to database, sqlite, couchbase, etc
try{
//my code to perform the task
}catch (Exception e){
}
}
public static void configurePeriodicSync(Context context, int syncInterval, int flexTime) {
Account account = getSyncAccount(context);
String authority = context.getString(R.string.content_authority);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// we can enable inexact timers in our periodic sync
SyncRequest request = new SyncRequest.Builder()
.syncPeriodic(syncInterval, flexTime)
.setSyncAdapter(account, authority)
.setExtras(new Bundle()).build();
ContentResolver.requestSync(request);
} else {
ContentResolver.addPeriodicSync(account, authority, new Bundle(), syncInterval);
}
}
public static void syncImmediately(Context context) {
Log.i("MyServiceSyncAdapter", "syncImmediately");
Bundle bundle = new Bundle();
bundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
ContentResolver.requestSync(getSyncAccount(context), context.getString(R.string.content_authority), bundle);
}
public static Account getSyncAccount(Context context) {
AccountManager accountManager = (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE); // Get an instance of the Android account manager
Account newAccount = new Account(context.getString(R.string.app_name), context.getString(R.string.sync_account_type)); // Create the account type and default account
// If the password doesn't exist, the account doesn't exist
if (accountManager.getPassword(newAccount) == null) {
if (!accountManager.addAccountExplicitly(newAccount, "", null)) {
Log.e("MyServiceSyncAdapter", "getSyncAccount Failed to create new account.");
return null;
}
onAccountCreated(newAccount, context);
}
return newAccount;
}
private static void onAccountCreated(Account newAccount, Context context) {
Log.i("MyServiceSyncAdapter", "onAccountCreated");
MyServiceSyncAdapter.configurePeriodicSync(context, SYNC_INTERVAL, SYNC_FLEXTIME);
ContentResolver.setSyncAutomatically(newAccount, context.getString(R.string.content_authority), true);
syncImmediately(context);
}
public static void initializeSyncAdapter(Context context) {
Log.d("MyServiceSyncAdapter", "initializeSyncAdapter");
getSyncAccount(context);
}
}
Upvotes: 4
Views: 457
Reputation: 62841
Are you sure the adapter is not firing and not just taking a very long time to run? From the documentation for syncPeriodic:
pollFrequency long: the amount of time in seconds that you wish to elapse between periodic syncs. A minimum period of 1 hour is enforced.
So, if you wait long enough, you may see your periodic sync start. I have timed this (slow day) and the sync does start...eventually.
Update
Based upon a demo sync app here, I recorded onPerformSync()
start times for APIs 23, 24 and 28. Times in the following table have been normalized to midnight. The sync period in all cases is attempted at one minute.
As you can see, onPerformSync()
runs about once per minute for API 23. However, API 24 and API 28 do seem to latch the time between calls to onPerformSync()
at 15 minutes give or take. APIs earlier than API 23 honor the one minute period request.
Recently, I haven't seen the one hour minimum, but I am sure I have in the past.
You may want to look into other ways to do syncing depending upon your requirements. Take a look at WorkManager, JobScheduler and AlarmManager in that order. (Use WorkManager
if you can though.)
Upvotes: 4