You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tasks/src-legacy/com/timsu/astrid/sync/SynchronizationService.java

150 lines
5.1 KiB
Java

package com.timsu.astrid.sync;
import java.util.Date;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import com.timsu.astrid.utilities.Constants;
import com.timsu.astrid.utilities.Preferences;
/**
* SynchronizationService is the service that performs Astrid's background
* synchronization with online task managers. Starting this service
* schedules a repeating alarm which handles the synchronization
*
* @author Tim Su
*
*/
public class SynchronizationService extends Service {
/** miniumum time before an auto-sync */
private static final long AUTO_SYNC_MIN_OFFSET = 5*60*1000L;
/** alarm identifier */
private static final String SYNC_ACTION = "sync";
// --- BroadcastReceiver abstract methods
/** Receive the alarm - start the synchronize service! */
@Override
public void onStart(Intent intent, int startId) {
Log.i("astrid", "wassup");
if(intent.getAction().equals(SYNC_ACTION))
startSynchronization(this);
}
/** Start the actual synchronization */
private void startSynchronization(Context context) {
if(context == null || context.getResources() == null)
return;
// figure out synchronization frequency
Integer syncFrequencySeconds = Preferences.getSyncAutoSyncFrequency(context);
if(syncFrequencySeconds == null)
return;
long interval = 1000L * syncFrequencySeconds;
long offset = computeNextSyncOffset(context, interval);
// if premature request for sync (i.e. user invoked manual sync,
// reschedule our service
if(offset != 0) {
Log.i("astrid", "Automatic Synchronize Postponed.");
return;
}
Log.i("astrid", "Automatic Synchronize Initiated.");
Preferences.setSyncLastSyncAttempt(context, new Date());
Synchronizer sync = new Synchronizer(true);
sync.synchronize(context, null);
}
// --- alarm management
/**
* Schedules repeating alarm for auto-synchronization
*/
public static void scheduleService(Context context) {
Integer syncFrequencySeconds = Preferences.getSyncAutoSyncFrequency(context);
if(syncFrequencySeconds == null) {
Log.w("sync-service", "disabled synchronization service");
unscheduleService(context);
return;
}
// figure out synchronization frequency
long interval = 1000L * syncFrequencySeconds;
long offset = computeNextSyncOffset(context, interval);
// give a little padding
offset = Math.max(offset, AUTO_SYNC_MIN_OFFSET);
AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getService(context, 0,
createAlarmIntent(context), PendingIntent.FLAG_UPDATE_CURRENT);
if (Constants.DEBUG)
Log.e("Astrid", "Autosync set for " + offset / 1000
+ " seconds repeating every " + syncFrequencySeconds);
// cancel all existing
am.cancel(pendingIntent);
// schedule new
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + offset,
interval, pendingIntent);
}
/**
* Removes repeating alarm for auto-synchronization
*/
public static void unscheduleService(Context context) {
AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getService(context, 0,
createAlarmIntent(context), PendingIntent.FLAG_UPDATE_CURRENT);
am.cancel(pendingIntent);
}
/** Create the alarm intent */
private static Intent createAlarmIntent(Context context) {
Intent intent = new Intent(context, SynchronizationService.class);
intent.setAction(SYNC_ACTION);
return intent;
}
// --- utility methods
private static long computeNextSyncOffset(Context context, long interval) {
// figure out last synchronize time
Date lastSyncDate = Preferences.getSyncLastSync(context);
Date lastAutoSyncDate = Preferences.getSyncLastSyncAttempt(context);
// if user never synchronized, give them a full offset period before bg sync
long latestSyncMillis = System.currentTimeMillis();
if(lastSyncDate != null)
latestSyncMillis = lastSyncDate.getTime();
if(lastAutoSyncDate != null && lastAutoSyncDate.getTime() > latestSyncMillis)
latestSyncMillis = lastAutoSyncDate.getTime();
long offset = 0;
if(latestSyncMillis != 0)
offset = Math.max(0, latestSyncMillis + interval - System.currentTimeMillis());
return offset;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}