diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
index a6bb02e32..fe7ad6ace 100644
--- a/src/main/AndroidManifest.xml
+++ b/src/main/AndroidManifest.xml
@@ -479,9 +479,6 @@
-
diff --git a/src/main/java/com/todoroo/astrid/dao/TaskDao.java b/src/main/java/com/todoroo/astrid/dao/TaskDao.java
index 809fc7a6b..40a91fb82 100644
--- a/src/main/java/com/todoroo/astrid/dao/TaskDao.java
+++ b/src/main/java/com/todoroo/astrid/dao/TaskDao.java
@@ -9,6 +9,7 @@ import android.content.ContentValues;
import android.database.sqlite.SQLiteConstraintException;
import com.todoroo.andlib.data.AbstractModel;
+import com.todoroo.andlib.data.Callback;
import com.todoroo.andlib.data.DatabaseDao;
import com.todoroo.andlib.data.Property;
import com.todoroo.andlib.data.TodorooCursor;
@@ -70,6 +71,10 @@ public class TaskDao {
return dao.query(query);
}
+ public void selectActive(Criterion criterion, Callback callback) {
+ dao.query(Query.select(Task.PROPERTIES).where(Criterion.and(TaskCriteria.isActive(), criterion)), callback);
+ }
+
public Task fetch(long id, Property>... properties) {
return dao.fetch(id, properties);
}
diff --git a/src/main/java/com/todoroo/astrid/data/Task.java b/src/main/java/com/todoroo/astrid/data/Task.java
index 83d27fc2d..4c21c66bf 100644
--- a/src/main/java/com/todoroo/astrid/data/Task.java
+++ b/src/main/java/com/todoroo/astrid/data/Task.java
@@ -225,6 +225,10 @@ public class Task extends RemoteModel {
return getValue(HIDE_UNTIL) > DateUtilities.now();
}
+ public boolean hasHideUntilDate() {
+ return getValue(HIDE_UNTIL) > 0;
+ }
+
/** Checks whether task is done. Requires DUE_DATE */
public boolean hasDueDate() {
return getValue(DUE_DATE) > 0;
diff --git a/src/main/java/org/tasks/Tasks.java b/src/main/java/org/tasks/Tasks.java
index fd3748a62..57e8ec61d 100644
--- a/src/main/java/org/tasks/Tasks.java
+++ b/src/main/java/org/tasks/Tasks.java
@@ -23,7 +23,6 @@ import org.tasks.analytics.Tracker;
import org.tasks.filters.FilterCounter;
import org.tasks.injection.InjectingApplication;
import org.tasks.preferences.Preferences;
-import org.tasks.scheduling.RefreshScheduler;
import org.tasks.sync.SyncThrottle;
import javax.inject.Inject;
@@ -51,7 +50,6 @@ public class Tasks extends InjectingApplication {
@Inject TagService tagService;
@Inject Broadcaster broadcaster;
@Inject FilterCounter filterCounter;
- @Inject RefreshScheduler refreshScheduler;
@Inject SyncThrottle syncThrottle;
@Inject Preferences preferences;
@Inject Tracker tracker;
diff --git a/src/main/java/org/tasks/injection/IntentServiceModule.java b/src/main/java/org/tasks/injection/IntentServiceModule.java
index 10d906eba..b9067bc35 100644
--- a/src/main/java/org/tasks/injection/IntentServiceModule.java
+++ b/src/main/java/org/tasks/injection/IntentServiceModule.java
@@ -10,7 +10,6 @@ import dagger.Module;
GeofenceSchedulingIntentService.class,
BackupIntentService.class,
GtasksBackgroundService.class,
- MidnightRefreshService.class,
RefreshSchedulerIntentService.class,
ReminderSchedulerIntentService.class,
GeofenceTransitionsIntentService.class,
diff --git a/src/main/java/org/tasks/scheduling/BackgroundScheduler.java b/src/main/java/org/tasks/scheduling/BackgroundScheduler.java
index 538b96208..d4ce1dbb8 100644
--- a/src/main/java/org/tasks/scheduling/BackgroundScheduler.java
+++ b/src/main/java/org/tasks/scheduling/BackgroundScheduler.java
@@ -17,7 +17,6 @@ public class BackgroundScheduler {
}
public void scheduleEverything() {
- context.startService(new Intent(context, RefreshSchedulerIntentService.class));
context.startService(new Intent(context, GeofenceSchedulingIntentService.class));
context.startService(new Intent(context, ReminderSchedulerIntentService.class));
scheduleBackupService();
@@ -33,7 +32,7 @@ public class BackgroundScheduler {
}
public void scheduleMidnightRefresh() {
- context.startService(new Intent(context, MidnightRefreshService.class));
+ context.startService(new Intent(context, RefreshSchedulerIntentService.class));
}
public void scheduleGtaskSync() {
diff --git a/src/main/java/org/tasks/scheduling/BackupIntentService.java b/src/main/java/org/tasks/scheduling/BackupIntentService.java
index 01dc7f97f..9bea02245 100644
--- a/src/main/java/org/tasks/scheduling/BackupIntentService.java
+++ b/src/main/java/org/tasks/scheduling/BackupIntentService.java
@@ -33,7 +33,7 @@ public class BackupIntentService extends MidnightIntentService {
}
@Override
- String getLastRunPreference() {
+ protected String getLastRunPreference() {
return TasksXmlExporter.PREF_BACKUP_LAST_DATE;
}
diff --git a/src/main/java/org/tasks/scheduling/MidnightIntentService.java b/src/main/java/org/tasks/scheduling/MidnightIntentService.java
index 934308b2b..1ede849cc 100644
--- a/src/main/java/org/tasks/scheduling/MidnightIntentService.java
+++ b/src/main/java/org/tasks/scheduling/MidnightIntentService.java
@@ -10,9 +10,10 @@ import javax.inject.Inject;
import timber.log.Timber;
+import static com.google.common.base.Strings.isNullOrEmpty;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.tasks.time.DateTimeUtils.currentTimeMillis;
-import static org.tasks.date.DateTimeUtils.newDateTime;
+import static org.tasks.time.DateTimeUtils.nextMidnight;
import static org.tasks.time.DateTimeUtils.printTimestamp;
public abstract class MidnightIntentService extends InjectingIntentService {
@@ -22,8 +23,11 @@ public abstract class MidnightIntentService extends InjectingIntentService {
@Inject Preferences preferences;
@Inject AlarmManager alarmManager;
+ private final String name;
+
public MidnightIntentService(String name) {
super(name);
+ this.name = name;
}
@Override
@@ -36,22 +40,22 @@ public abstract class MidnightIntentService extends InjectingIntentService {
if (nextRun <= now) {
nextRun = nextMidnight(now);
- Timber.d("running now [nextRun=%s]", printTimestamp(nextRun));
- preferences.setLong(getLastRunPreference(), now);
+ Timber.d("%s running now [nextRun=%s]", name, printTimestamp(nextRun));
+ if (!isNullOrEmpty(getLastRunPreference())) {
+ preferences.setLong(getLastRunPreference(), now);
+ }
run();
} else {
- Timber.d("will run at %s [lastRun=%s]", printTimestamp(nextRun), printTimestamp(lastRun));
+ Timber.d("%s will run at %s [lastRun=%s]", name, printTimestamp(nextRun), printTimestamp(lastRun));
}
PendingIntent pendingIntent = PendingIntent.getService(this, 0, new Intent(this, this.getClass()), PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.noWakeup(nextRun + PADDING, pendingIntent);
}
- private static long nextMidnight(long timestamp) {
- return newDateTime(timestamp).startOfDay().plusDays(1).getMillis();
- }
-
abstract void run();
- abstract String getLastRunPreference();
+ protected String getLastRunPreference() {
+ return null;
+ }
}
diff --git a/src/main/java/org/tasks/scheduling/MidnightRefreshService.java b/src/main/java/org/tasks/scheduling/MidnightRefreshService.java
deleted file mode 100644
index 242400a24..000000000
--- a/src/main/java/org/tasks/scheduling/MidnightRefreshService.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package org.tasks.scheduling;
-
-import org.tasks.Broadcaster;
-
-import javax.inject.Inject;
-
-public class MidnightRefreshService extends MidnightIntentService {
-
- @Inject Broadcaster broadcaster;
-
- public MidnightRefreshService() {
- super(MidnightRefreshService.class.getSimpleName());
- }
-
- @Override
- void run() {
- broadcaster.refresh();
- }
-
- @Override
- String getLastRunPreference() {
- return "midnightRefreshDate";
- }
-}
diff --git a/src/main/java/org/tasks/scheduling/RefreshScheduler.java b/src/main/java/org/tasks/scheduling/RefreshScheduler.java
index 55976d65c..8c60eda82 100644
--- a/src/main/java/org/tasks/scheduling/RefreshScheduler.java
+++ b/src/main/java/org/tasks/scheduling/RefreshScheduler.java
@@ -4,10 +4,8 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
-import com.todoroo.andlib.data.Property;
-import com.todoroo.andlib.data.TodorooCursor;
+import com.todoroo.andlib.data.Callback;
import com.todoroo.andlib.sql.Criterion;
-import com.todoroo.andlib.sql.Query;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task;
@@ -15,24 +13,21 @@ import org.tasks.injection.ForApplication;
import org.tasks.receivers.RefreshReceiver;
import javax.inject.Inject;
-import javax.inject.Singleton;
+
+import timber.log.Timber;
import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
import static com.todoroo.andlib.utility.DateUtilities.ONE_MINUTE;
import static org.tasks.time.DateTimeUtils.currentTimeMillis;
+import static org.tasks.time.DateTimeUtils.nextMidnight;
+import static org.tasks.time.DateTimeUtils.printTimestamp;
-@Singleton
public class RefreshScheduler {
private final TaskDao taskDao;
private final Context context;
private final AlarmManager alarmManager;
- private static final Property>[] REFRESH_PROPERTIES = new Property>[]{
- Task.DUE_DATE,
- Task.HIDE_UNTIL
- };
-
@Inject
public RefreshScheduler(TaskDao taskDao, @ForApplication Context context, AlarmManager alarmManager) {
this.taskDao = taskDao;
@@ -41,45 +36,39 @@ public class RefreshScheduler {
}
public void scheduleApplicationRefreshes() {
- TodorooCursor cursor = getTasks();
- try {
- for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
- Task task = new Task(cursor);
+ long now = currentTimeMillis();
+ long midnight = nextMidnight(now);
+ Criterion criterion = Criterion.or(
+ Criterion.and(Task.HIDE_UNTIL.gt(now), Task.HIDE_UNTIL.lt(midnight)),
+ Criterion.and(Task.DUE_DATE.gt(now), Task.DUE_DATE.lt(midnight)));
+ taskDao.selectActive(criterion, new Callback() {
+ @Override
+ public void apply(Task task) {
scheduleRefresh(task);
}
- } finally {
- cursor.close();
- }
+ });
}
public void scheduleRefresh(Task task) {
- if (task.containsValue(Task.DUE_DATE)) {
+ if (task.isCompleted()) {
+ scheduleRefresh(task.getCompletionDate() + ONE_MINUTE);
+ } else if (task.hasDueDate()) {
scheduleRefresh(task.getDueDate());
}
- if (task.containsValue(Task.HIDE_UNTIL)) {
+ if (task.hasHideUntilDate()) {
scheduleRefresh(task.getHideUntil());
}
- if (task.containsValue(Task.COMPLETION_DATE)) {
- scheduleRefresh(task.getCompletionDate() + ONE_MINUTE);
- }
- }
-
- private void scheduleRefresh(Long dueDate) {
- if (currentTimeMillis() > dueDate) {
- return;
- }
-
- dueDate += 1000; // this is ghetto
- Intent intent = new Intent(context, RefreshReceiver.class);
- intent.setAction(Long.toString(dueDate));
- PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, FLAG_UPDATE_CURRENT);
- alarmManager.noWakeup(dueDate, pendingIntent);
}
- private TodorooCursor getTasks() {
+ private void scheduleRefresh(Long refreshTime) {
long now = currentTimeMillis();
- return taskDao.query(Query.select(REFRESH_PROPERTIES).where(Criterion.and(
- TaskDao.TaskCriteria.isActive(),
- Criterion.or(Task.HIDE_UNTIL.gt(now), Task.DUE_DATE.gt(now)))));
+ if (now < refreshTime && refreshTime < nextMidnight(now)) {
+ refreshTime += 1000; // this is ghetto
+ Timber.d("Scheduling refresh at %s", printTimestamp(refreshTime));
+ Intent intent = new Intent(context, RefreshReceiver.class);
+ intent.setAction(Long.toString(refreshTime));
+ PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, FLAG_UPDATE_CURRENT);
+ alarmManager.noWakeup(refreshTime, pendingIntent);
+ }
}
}
diff --git a/src/main/java/org/tasks/scheduling/RefreshSchedulerIntentService.java b/src/main/java/org/tasks/scheduling/RefreshSchedulerIntentService.java
index 9b46a02a1..4f82da2fe 100644
--- a/src/main/java/org/tasks/scheduling/RefreshSchedulerIntentService.java
+++ b/src/main/java/org/tasks/scheduling/RefreshSchedulerIntentService.java
@@ -1,15 +1,12 @@
package org.tasks.scheduling;
-import android.content.Intent;
-
-import org.tasks.injection.InjectingIntentService;
+import org.tasks.Broadcaster;
import javax.inject.Inject;
-import timber.log.Timber;
-
-public class RefreshSchedulerIntentService extends InjectingIntentService {
+public class RefreshSchedulerIntentService extends MidnightIntentService {
+ @Inject Broadcaster broadcaster;
@Inject RefreshScheduler refreshScheduler;
public RefreshSchedulerIntentService() {
@@ -17,11 +14,8 @@ public class RefreshSchedulerIntentService extends InjectingIntentService {
}
@Override
- protected void onHandleIntent(Intent intent) {
- super.onHandleIntent(intent);
-
- Timber.d("onHandleIntent(%s)", intent);
-
+ void run() {
refreshScheduler.scheduleApplicationRefreshes();
+ broadcaster.refresh();
}
}
diff --git a/src/main/java/org/tasks/time/DateTimeUtils.java b/src/main/java/org/tasks/time/DateTimeUtils.java
index d6477d578..bcf23bcb4 100644
--- a/src/main/java/org/tasks/time/DateTimeUtils.java
+++ b/src/main/java/org/tasks/time/DateTimeUtils.java
@@ -1,7 +1,11 @@
package org.tasks.time;
+import org.tasks.BuildConfig;
+
import java.util.Date;
+import static org.tasks.date.DateTimeUtils.newDateTime;
+
public class DateTimeUtils {
private static final SystemMillisProvider SYSTEM_MILLIS_PROVIDER = new SystemMillisProvider();
@@ -19,7 +23,13 @@ public class DateTimeUtils {
MILLIS_PROVIDER = SYSTEM_MILLIS_PROVIDER;
}
+ public static long nextMidnight(long timestamp) {
+ return newDateTime(timestamp).startOfDay().plusDays(1).getMillis();
+ }
+
public static String printTimestamp(long timestamp) {
- return new Date(timestamp).toString();
+ return BuildConfig.DEBUG
+ ? new Date(timestamp).toString()
+ : Long.toString(timestamp);
}
}