forked from thaagenson/astridApi
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Tim Su
committed
Sep 29, 2010
1 parent
9eb1ab6
commit 42dcb79
Showing
1 changed file
with
150 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
package com.todoroo.astrid.sync; | ||
|
||
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.todoroo.andlib.service.Autowired; | ||
import com.todoroo.andlib.service.ContextManager; | ||
import com.todoroo.andlib.service.DependencyInjectionService; | ||
import com.todoroo.andlib.service.ExceptionService; | ||
import com.todoroo.andlib.utility.DateUtilities; | ||
import com.todoroo.andlib.utility.Preferences; | ||
|
||
/** | ||
* Performs synchronization service logic in background service to avoid | ||
* ANR (application not responding) messages. | ||
* <p> | ||
* Starting this service | ||
* schedules a repeating alarm which handles | ||
* synchronization with your serv | ||
* | ||
* @author Tim Su | ||
* | ||
*/ | ||
abstract public class SyncBackgroundService extends Service { | ||
|
||
/** Minimum time before an auto-sync */ | ||
private static final long AUTO_SYNC_MIN_OFFSET = 5*60*1000L; | ||
|
||
/** alarm identifier */ | ||
public static final String SYNC_ACTION = "sync"; //$NON-NLS-1$ | ||
|
||
@Autowired private ExceptionService exceptionService; | ||
|
||
// --- abstract methods | ||
|
||
abstract protected SyncProvider<?> getSyncProvider(); | ||
|
||
abstract protected SyncProviderUtilities getSyncUtilities(); | ||
|
||
// --- implementation | ||
|
||
public SyncBackgroundService() { | ||
DependencyInjectionService.getInstance().inject(this); | ||
} | ||
|
||
/** Receive the alarm - start the synchronize service! */ | ||
@Override | ||
public void onStart(Intent intent, int startId) { | ||
try { | ||
if(intent != null && SYNC_ACTION.equals(intent.getAction())) | ||
startSynchronization(this); | ||
} catch (Exception e) { | ||
exceptionService.reportError(getSyncUtilities().getIdentifier() + "-bg-sync", e); //$NON-NLS-1$ | ||
} | ||
} | ||
|
||
/** Start the actual synchronization */ | ||
private void startSynchronization(Context context) { | ||
if(context == null || context.getResources() == null) | ||
return; | ||
|
||
ContextManager.setContext(context); | ||
|
||
if(!getSyncUtilities().isLoggedIn()) | ||
return; | ||
|
||
getSyncProvider().synchronize(context); | ||
} | ||
|
||
|
||
@Override | ||
public IBinder onBind(Intent intent) { | ||
return null; | ||
} | ||
|
||
// --- alarm management | ||
|
||
/** | ||
* Schedules repeating alarm for auto-synchronization | ||
*/ | ||
public void scheduleService() { | ||
int syncFrequencySeconds = Preferences.getIntegerFromString( | ||
getSyncUtilities().getSyncIntervalKey(), -1); | ||
Context context = ContextManager.getContext(); | ||
if(syncFrequencySeconds <= 0) { | ||
unscheduleService(context); | ||
return; | ||
} | ||
|
||
// figure out synchronization frequency | ||
long interval = 1000L * syncFrequencySeconds; | ||
long offset = computeNextSyncOffset(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); | ||
|
||
Log.i("Astrid", "Autosync set for " + offset / 1000 //$NON-NLS-1$ //$NON-NLS-2$ | ||
+ " seconds repeating every " + syncFrequencySeconds); //$NON-NLS-1$ | ||
|
||
// cancel all existing | ||
am.cancel(pendingIntent); | ||
|
||
// schedule new | ||
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + offset, | ||
interval, pendingIntent); | ||
} | ||
|
||
|
||
/** | ||
* Removes repeating alarm for auto-synchronization | ||
*/ | ||
private 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 Intent createAlarmIntent(Context context) { | ||
Intent intent = new Intent(context, getClass()); | ||
intent.setAction(SYNC_ACTION); | ||
return intent; | ||
} | ||
|
||
// --- utility methods | ||
|
||
|
||
private long computeNextSyncOffset(long interval) { | ||
// figure out last synchronize time | ||
long lastSyncDate = getSyncUtilities().getLastSyncDate(); | ||
|
||
// if user never synchronized, give them a full offset period before bg sync | ||
if(lastSyncDate != 0) | ||
return Math.max(0, lastSyncDate + interval - DateUtilities.now()); | ||
else | ||
return interval; | ||
} | ||
|
||
|
||
} |