When reminders are mass scheduled, reminders for now are spread out

pull/14/head
Sam Bosley 13 years ago
parent e5b499d075
commit 5ddf619907

@ -72,6 +72,8 @@ public final class ReminderService {
private AlarmScheduler scheduler = new ReminderAlarmScheduler();
private long now = -1; // For tracking when reminders might be scheduled all at once
private ReminderService() {
DependencyInjectionService.getInstance().inject(this);
setPreferenceDefaults();
@ -121,6 +123,7 @@ public final class ReminderService {
TodorooCursor<Task> cursor = getTasksWithReminders(PROPERTIES);
try {
Task task = new Task();
now = DateUtilities.now(); // Before mass scheduling, initialize now variable
for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
task.readFromCursor(cursor);
scheduleAlarm(task, false);
@ -129,9 +132,15 @@ public final class ReminderService {
// suppress
} finally {
cursor.close();
now = -1; // Signal done with now variable
}
}
private long getNowValue() {
// If we're in the midst of mass scheduling, use the prestored now var
return (now == -1 ? DateUtilities.now() : now);
}
private static final long NO_ALARM = Long.MAX_VALUE;
/**
@ -189,9 +198,18 @@ public final class ReminderService {
// notifications at due date
long whenDueDate = calculateNextDueDateReminder(task);
// notifications after due date
long whenOverdue = calculateNextOverdueReminder(task);
// For alarms around/before now, increment the now value so the next one will be later
if (whenDueDate <= now || whenOverdue <= now) {
whenDueDate = now;
whenOverdue = now;
now += 30 * DateUtilities.ONE_MINUTE; // Prevents overdue tasks from being scheduled all at once
}
// if random reminders are too close to due date, favor due date
if(whenRandom != NO_ALARM && whenDueDate - whenRandom < DateUtilities.ONE_DAY)
whenRandom = NO_ALARM;
@ -235,22 +253,23 @@ public final class ReminderService {
* @return
*/
private long calculateNextOverdueReminder(Task task) {
// Uses getNowValue() instead of DateUtilities.now()
if(task.hasDueDate() && task.getFlag(Task.REMINDER_FLAGS, Task.NOTIFY_AFTER_DEADLINE)) {
long dueDate = task.getValue(Task.DUE_DATE);
long lastReminder = task.getValue(Task.REMINDER_LAST);
if(dueDate > DateUtilities.now())
if(dueDate > getNowValue())
return dueDate + (long)((0.5f + 2f * random.nextFloat()) * DateUtilities.ONE_HOUR);
if(lastReminder < dueDate)
return DateUtilities.now();
return getNowValue();
if(DateUtilities.now() - lastReminder < 6 * DateUtilities.ONE_HOUR)
return DateUtilities.now() + (long)((2.0f +
if(getNowValue() - lastReminder < 6 * DateUtilities.ONE_HOUR)
return getNowValue() + (long)((2.0f +
task.getValue(Task.IMPORTANCE) +
6f * random.nextFloat()) * DateUtilities.ONE_HOUR);
return DateUtilities.now();
return getNowValue();
}
return NO_ALARM;
}
@ -269,9 +288,10 @@ public final class ReminderService {
* @return
*/
private long calculateNextDueDateReminder(Task task) {
// Uses getNowValue() instead of DateUtilities.now()
if(task.hasDueDate() && task.getFlag(Task.REMINDER_FLAGS, Task.NOTIFY_AT_DEADLINE)) {
long dueDate = task.getValue(Task.DUE_DATE);
long lastReminder = task.getValue(Task.REMINDER_LAST);;
long lastReminder = task.getValue(Task.REMINDER_LAST);
long dueDateAlarm;
@ -285,7 +305,7 @@ public final class ReminderService {
date.setMinutes(0);
date.setSeconds(0);
dueDateAlarm = date.getTime();
if (dueDate > DateUtilities.now() && dueDateAlarm < DateUtilities.now()) {
if (dueDate > getNowValue() && dueDateAlarm < getNowValue()) {
// this only happens for tasks due today, cause dueDateAlarm wouldnt be in the past otherwise
// if the default reminder is in the past, then reschedule it
// on this day before start of quiet hours or after quiet hours
@ -302,8 +322,8 @@ public final class ReminderService {
quietHoursEndDate.setMinutes(0);
quietHoursEndDate.setSeconds(0);
long millisToQuiet = quietHoursStartDate.getTime() - DateUtilities.now();
long millisToEndOfDay = dueDate - DateUtilities.now();
long millisToQuiet = quietHoursStartDate.getTime() - getNowValue();
long millisToEndOfDay = dueDate - getNowValue();
//
int periodDivFactor = 4;
@ -318,17 +338,17 @@ public final class ReminderService {
dueDateAlarm = date.getTime();
} else if (hour < quietHoursStart) {
// quietHours didnt start yet
millisToQuiet = quietHoursStartDate.getTime() - DateUtilities.now();
millisToQuiet = quietHoursStartDate.getTime() - getNowValue();
long millisAfterQuiet = dueDate - quietHoursEndDate.getTime();
// if there is more time after quiethours today, select quiethours-end for reminder
if (millisAfterQuiet > (millisToQuiet / ((float)(1-(1/periodDivFactor))) ))
dueDateAlarm = quietHoursEndDate.getTime();
else
dueDateAlarm = DateUtilities.now() + (long)(millisToQuiet / periodDivFactor);
dueDateAlarm = getNowValue() + (long)(millisToQuiet / periodDivFactor);
} else {
// after quietHours, reuse dueDate for end of day
dueDateAlarm = DateUtilities.now() + (long)(millisToEndOfDay / periodDivFactor);
dueDateAlarm = getNowValue() + (long)(millisToEndOfDay / periodDivFactor);
}
} else { // wrap across 24/hour boundary
if(hour >= quietHoursStart) {
@ -339,16 +359,16 @@ public final class ReminderService {
dueDateAlarm = date.getTime();
} else {
// quietHours didnt start yet
millisToQuiet = quietHoursStartDate.getTime() - DateUtilities.now();
dueDateAlarm = DateUtilities.now() + (long)(millisToQuiet / periodDivFactor);
millisToQuiet = quietHoursStartDate.getTime() - getNowValue();
dueDateAlarm = getNowValue() + (long)(millisToQuiet / periodDivFactor);
}
}
} else {
// Quiet hours not activated, simply schedule the reminder on 1/periodDivFactor towards the end of day
dueDateAlarm = DateUtilities.now() + (long)(millisToEndOfDay / periodDivFactor);
dueDateAlarm = getNowValue() + (long)(millisToEndOfDay / periodDivFactor);
}
if(dueDate > DateUtilities.now() && dueDateAlarm < DateUtilities.now())
if(dueDate > getNowValue() && dueDateAlarm < getNowValue())
dueDateAlarm = dueDate;
}
}

Loading…
Cancel
Save