diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
index 9b47f1067..3ac54c1b9 100644
--- a/src/main/AndroidManifest.xml
+++ b/src/main/AndroidManifest.xml
@@ -344,20 +344,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -496,16 +482,19 @@
android:name=".scheduling.AlarmSchedulingIntentService"
android:exported="false" />
+
diff --git a/src/main/java/com/todoroo/astrid/gtasks/GtasksBackgroundService.java b/src/main/java/com/todoroo/astrid/gtasks/GtasksBackgroundService.java
deleted file mode 100644
index e29584351..000000000
--- a/src/main/java/com/todoroo/astrid/gtasks/GtasksBackgroundService.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * Copyright (c) 2012 Todoroo Inc
- *
- * See the file "LICENSE" for the full license governing this code.
- */
-package com.todoroo.astrid.gtasks;
-
-import android.content.Intent;
-import android.os.IBinder;
-
-import com.todoroo.andlib.service.ContextManager;
-import com.todoroo.astrid.gtasks.sync.GtasksSyncV2Provider;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.tasks.Broadcaster;
-import org.tasks.injection.InjectingService;
-import org.tasks.sync.RecordSyncStatusCallback;
-
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import javax.inject.Inject;
-
-public class GtasksBackgroundService extends InjectingService {
-
- private static final Logger log = LoggerFactory.getLogger(GtasksBackgroundService.class);
-
- @Inject GtasksPreferenceService gtasksPreferenceService;
- @Inject GtasksSyncV2Provider gtasksSyncV2Provider;
- @Inject Broadcaster broadcaster;
-
- private final AtomicBoolean started = new AtomicBoolean(false);
-
- /** Receive the alarm - start the synchronize service! */
- @Override
- public void onStart(Intent intent, int startId) {
- try {
- if(intent != null && !started.getAndSet(true)) {
- ContextManager.setContext(this);
-
- if(gtasksPreferenceService.isLoggedIn() && gtasksSyncV2Provider.isActive()) {
- gtasksSyncV2Provider.synchronizeActiveTasks(new RecordSyncStatusCallback(gtasksPreferenceService, broadcaster));
- }
- }
- } catch (Exception e) {
- log.error(e.getMessage(), e);
- }
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
-}
diff --git a/src/main/java/com/todoroo/astrid/gtasks/GtasksPreferences.java b/src/main/java/com/todoroo/astrid/gtasks/GtasksPreferences.java
index 5dadc5c12..5ba4a0596 100644
--- a/src/main/java/com/todoroo/astrid/gtasks/GtasksPreferences.java
+++ b/src/main/java/com/todoroo/astrid/gtasks/GtasksPreferences.java
@@ -24,6 +24,7 @@ import com.todoroo.astrid.gtasks.sync.GtasksSyncV2Provider;
import org.tasks.R;
import org.tasks.injection.InjectingSyncProviderPreferences;
+import org.tasks.scheduling.BackgroundScheduler;
import java.util.HashMap;
import java.util.Set;
@@ -43,7 +44,7 @@ public class GtasksPreferences extends InjectingSyncProviderPreferences {
@Inject GtasksPreferenceService gtasksPreferenceService;
@Inject GtasksSyncV2Provider gtasksSyncV2Provider;
- @Inject GtasksScheduler gtasksScheduler;
+ @Inject BackgroundScheduler backgroundScheduler;
@Override
public int getPreferenceResource() {
@@ -88,7 +89,7 @@ public class GtasksPreferences extends InjectingSyncProviderPreferences {
@Override
protected void onPause() {
super.onPause();
- gtasksScheduler.scheduleService();
+ backgroundScheduler.scheduleGtaskSync();
}
public static final int RESULT_CODE_SYNCHRONIZE = 2;
diff --git a/src/main/java/com/todoroo/astrid/gtasks/GtasksScheduler.java b/src/main/java/com/todoroo/astrid/gtasks/GtasksScheduler.java
deleted file mode 100644
index a405baadd..000000000
--- a/src/main/java/com/todoroo/astrid/gtasks/GtasksScheduler.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package com.todoroo.astrid.gtasks;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-
-import com.todoroo.andlib.utility.DateUtilities;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.tasks.injection.ForApplication;
-import org.tasks.preferences.Preferences;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-@Singleton
-public class GtasksScheduler {
-
- private static final Logger log = LoggerFactory.getLogger(GtasksScheduler.class);
-
- /** Minimum time before an auto-sync */
- private static final long AUTO_SYNC_MIN_OFFSET = 5*60*1000L;
-
- private final GtasksPreferenceService gtasksPreferenceService;
- private Context context;
- private Preferences preferences;
-
- @Inject
- public GtasksScheduler(GtasksPreferenceService gtasksPreferenceService, @ForApplication Context context, Preferences preferences) {
- this.gtasksPreferenceService = gtasksPreferenceService;
- this.context = context;
- this.preferences = preferences;
- }
-
- /**
- * Schedules repeating alarm for auto-synchronization
- */
- public void scheduleService() {
- int syncFrequencySeconds = 0;
- try {
- syncFrequencySeconds = preferences.getIntegerFromString(
- gtasksPreferenceService.getSyncIntervalKey(), -1);
- } catch(ClassCastException e) {
- log.error(e.getMessage(), e);
- preferences.setStringFromInteger(gtasksPreferenceService.getSyncIntervalKey(), 0);
- }
- 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, gtasksPreferenceService.getSyncIntervalKey(),
- createAlarmIntent(context), PendingIntent.FLAG_UPDATE_CURRENT);
-
- log.info("Autosync set for {} seconds repeating every {}", offset / 1000, 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, gtasksPreferenceService.getSyncIntervalKey(),
- createAlarmIntent(context), PendingIntent.FLAG_UPDATE_CURRENT);
- am.cancel(pendingIntent);
- }
-
- /** Create the alarm intent */
- private Intent createAlarmIntent(Context context) {
- return new Intent(context, GtasksBackgroundService.class);
- }
-
- // --- utility methods
-
- private long computeNextSyncOffset(long interval) {
- // figure out last synchronize time
- long lastSyncDate = gtasksPreferenceService.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;
- }
- }
-}
diff --git a/src/main/java/com/todoroo/astrid/gtasks/GtasksStartupReceiver.java b/src/main/java/com/todoroo/astrid/gtasks/GtasksStartupReceiver.java
deleted file mode 100644
index ee159436e..000000000
--- a/src/main/java/com/todoroo/astrid/gtasks/GtasksStartupReceiver.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Copyright (c) 2012 Todoroo Inc
- *
- * See the file "LICENSE" for the full license governing this code.
- */
-package com.todoroo.astrid.gtasks;
-
-import android.content.Context;
-import android.content.Intent;
-
-import com.todoroo.andlib.service.ContextManager;
-
-import org.tasks.injection.InjectingBroadcastReceiver;
-
-import javax.inject.Inject;
-
-public class GtasksStartupReceiver extends InjectingBroadcastReceiver {
-
- @Inject GtasksScheduler scheduler;
-
- @Override
- public void onReceive(final Context context, Intent intent) {
- super.onReceive(context, intent);
- ContextManager.setContext(context);
- scheduler.scheduleService();
- }
-}
diff --git a/src/main/java/org/tasks/injection/BroadcastModule.java b/src/main/java/org/tasks/injection/BroadcastModule.java
index 6963ed5d6..48dc4f2dd 100644
--- a/src/main/java/org/tasks/injection/BroadcastModule.java
+++ b/src/main/java/org/tasks/injection/BroadcastModule.java
@@ -9,7 +9,6 @@ import com.todoroo.astrid.gcal.CalendarStartupReceiver;
import com.todoroo.astrid.gcal.GCalTaskCompleteListener;
import com.todoroo.astrid.gtasks.GtasksCustomFilterCriteriaExposer;
import com.todoroo.astrid.gtasks.GtasksFilterExposer;
-import com.todoroo.astrid.gtasks.GtasksStartupReceiver;
import com.todoroo.astrid.reminders.Notifications;
import com.todoroo.astrid.reminders.ShowNotificationReceiver;
import com.todoroo.astrid.repeats.RepeatTaskCompleteListener;
@@ -37,7 +36,6 @@ import dagger.Module;
TimerTaskCompleteListener.class,
RepeatTaskCompleteListener.class,
AlarmTaskRepeatListener.class,
- GtasksStartupReceiver.class,
PhoneStateChangedReceiver.class,
ShowNotificationReceiver.class,
CoreFilterExposer.class,
diff --git a/src/main/java/org/tasks/injection/IntentServiceModule.java b/src/main/java/org/tasks/injection/IntentServiceModule.java
index 2d9ca11d8..baa4f91be 100644
--- a/src/main/java/org/tasks/injection/IntentServiceModule.java
+++ b/src/main/java/org/tasks/injection/IntentServiceModule.java
@@ -8,6 +8,7 @@ import dagger.Module;
injects = {
AlarmSchedulingIntentService.class,
BackupIntentService.class,
+ GtasksBackgroundService.class,
MidnightRefreshService.class,
RefreshSchedulerIntentService.class,
ReminderSchedulerIntentService.class
diff --git a/src/main/java/org/tasks/injection/ServiceModule.java b/src/main/java/org/tasks/injection/ServiceModule.java
index a80601e2d..8ec721b14 100644
--- a/src/main/java/org/tasks/injection/ServiceModule.java
+++ b/src/main/java/org/tasks/injection/ServiceModule.java
@@ -1,6 +1,5 @@
package org.tasks.injection;
-import com.todoroo.astrid.gtasks.GtasksBackgroundService;
import com.todoroo.astrid.widget.WidgetUpdateService;
import org.tasks.widget.ScrollableWidgetUpdateService;
@@ -9,7 +8,6 @@ import dagger.Module;
@Module(addsTo = TasksModule.class,
injects = {
- GtasksBackgroundService.class,
ScrollableWidgetUpdateService.class,
WidgetUpdateService.class
})
diff --git a/src/main/java/org/tasks/preferences/Preferences.java b/src/main/java/org/tasks/preferences/Preferences.java
index d7d62d530..3469252ed 100644
--- a/src/main/java/org/tasks/preferences/Preferences.java
+++ b/src/main/java/org/tasks/preferences/Preferences.java
@@ -98,6 +98,10 @@ public class Preferences {
}
}
+ public void setString(int key, String newValue) {
+ setString(context.getString(key), newValue);
+ }
+
public void setString(String key, String newValue) {
Editor editor = prefs.edit();
editor.putString(key, newValue);
diff --git a/src/main/java/org/tasks/scheduling/BackgroundScheduler.java b/src/main/java/org/tasks/scheduling/BackgroundScheduler.java
index 1fb7d88c0..625d5e805 100644
--- a/src/main/java/org/tasks/scheduling/BackgroundScheduler.java
+++ b/src/main/java/org/tasks/scheduling/BackgroundScheduler.java
@@ -21,6 +21,7 @@ public class BackgroundScheduler {
context.startService(new Intent(context, ReminderSchedulerIntentService.class));
scheduleBackupService();
scheduleMidnightRefresh();
+ scheduleGtaskSync();
}
public void scheduleBackupService() {
@@ -30,4 +31,8 @@ public class BackgroundScheduler {
public void scheduleMidnightRefresh() {
context.startService(new Intent(context, MidnightRefreshService.class));
}
+
+ public void scheduleGtaskSync() {
+ context.startService(new Intent(context, GtasksBackgroundService.class));
+ }
}
diff --git a/src/main/java/org/tasks/scheduling/GtasksBackgroundService.java b/src/main/java/org/tasks/scheduling/GtasksBackgroundService.java
new file mode 100644
index 000000000..a2a0a9d19
--- /dev/null
+++ b/src/main/java/org/tasks/scheduling/GtasksBackgroundService.java
@@ -0,0 +1,59 @@
+package org.tasks.scheduling;
+
+import com.todoroo.astrid.gtasks.GtasksPreferenceService;
+import com.todoroo.astrid.gtasks.sync.GtasksSyncV2Provider;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.tasks.Broadcaster;
+import org.tasks.R;
+import org.tasks.preferences.Preferences;
+import org.tasks.sync.RecordSyncStatusCallback;
+
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+
+import static java.util.concurrent.TimeUnit.MINUTES;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+public class GtasksBackgroundService extends RecurringIntervalIntentService {
+
+ private static final Logger log = LoggerFactory.getLogger(GtasksBackgroundService.class);
+
+ @Inject Preferences preferences;
+ @Inject GtasksPreferenceService gtasksPreferenceService;
+ @Inject GtasksSyncV2Provider gtasksSyncV2Provider;
+ @Inject Broadcaster broadcaster;
+
+ public GtasksBackgroundService() {
+ super(GtasksBackgroundService.class.getSimpleName());
+ }
+
+ @Override
+ void run() {
+ if (gtasksPreferenceService.isOngoing()) {
+ log.debug("aborting: sync ongoing");
+ return;
+ }
+ if(gtasksPreferenceService.isLoggedIn() && gtasksSyncV2Provider.isActive()) {
+ gtasksSyncV2Provider.synchronizeActiveTasks(new RecordSyncStatusCallback(gtasksPreferenceService, broadcaster));
+ }
+ }
+
+ @Override
+ long intervalMillis() {
+ try {
+ return SECONDS.toMillis(preferences.getIntegerFromString(R.string.gtasks_GPr_interval_key, 0));
+ } catch(Exception e) {
+ log.error(e.getMessage(), e);
+ preferences.setString(R.string.gtasks_GPr_interval_key, "0");
+ return 0;
+ }
+ }
+
+ @Override
+ String getLastRunPreference() {
+ return "gtasks_last_sync";
+ }
+}
diff --git a/src/main/java/org/tasks/scheduling/RecurringIntervalIntentService.java b/src/main/java/org/tasks/scheduling/RecurringIntervalIntentService.java
new file mode 100644
index 000000000..8fb6206da
--- /dev/null
+++ b/src/main/java/org/tasks/scheduling/RecurringIntervalIntentService.java
@@ -0,0 +1,65 @@
+package org.tasks.scheduling;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.tasks.injection.InjectingIntentService;
+import org.tasks.preferences.Preferences;
+
+import javax.inject.Inject;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.tasks.date.DateTimeUtils.currentTimeMillis;
+import static org.tasks.date.DateTimeUtils.newDateTime;
+
+public abstract class RecurringIntervalIntentService extends InjectingIntentService {
+
+ private static final Logger log = LoggerFactory.getLogger(RecurringIntervalIntentService.class);
+
+ private static final long PADDING = SECONDS.toMillis(1);
+
+ @Inject Preferences preferences;
+
+ public RecurringIntervalIntentService(String name) {
+ super(name);
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ super.onHandleIntent(intent);
+
+ long interval = intervalMillis();
+
+ if (interval <= 0) {
+ log.debug("service disabled");
+ return;
+ }
+
+ long lastRun = preferences.getLong(getLastRunPreference(), 0);
+ long now = currentTimeMillis();
+ long nextRun = lastRun + interval;
+
+ if (nextRun < now + PADDING) {
+ nextRun = now + interval;
+ log.debug("running now [nextRun={}]", newDateTime(nextRun));
+ preferences.setLong(getLastRunPreference(), now);
+ run();
+ } else {
+ log.debug("will run at {} [lastRun={}]", newDateTime(nextRun), newDateTime(lastRun));
+ }
+
+ AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
+ PendingIntent pendingIntent = PendingIntent.getService(this, 0, new Intent(this, this.getClass()), PendingIntent.FLAG_UPDATE_CURRENT);
+ alarmManager.set(AlarmManager.RTC, nextRun, pendingIntent);
+ }
+
+ abstract void run();
+
+ abstract long intervalMillis();
+
+ abstract String getLastRunPreference();
+}