forked from thaagenson/astridApi
-
Notifications
You must be signed in to change notification settings - Fork 0
/
SyncBackgroundService.java
150 lines (115 loc) · 4.55 KB
/
SyncBackgroundService.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
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;
}
}