Updated snooze to move repeating alarms instead of scheduling an additional alarm. Also updated repeat to move alarms.

pull/14/head
Tim Su 17 years ago
parent 5d07f907ee
commit 9ede7a31f7

@ -221,8 +221,7 @@ public class TaskEdit extends TaskModificationTabbedActivity<TaskModelForEdit> {
// alerts // alerts
if(model.getTaskIdentifier() != null) { if(model.getTaskIdentifier() != null) {
List<Date> alerts = alertController.getTaskAlerts(this, List<Date> alerts = alertController.getTaskAlerts(model.getTaskIdentifier());
model.getTaskIdentifier());
for(Date alert : alerts) { for(Date alert : alerts) {
addAlert(alert); addAlert(alert);
} }

@ -19,15 +19,25 @@ public class TaskViewNotifier extends TaskView {
// bundle tokens // bundle tokens
public static final String FROM_NOTIFICATION_TOKEN = "notify"; public static final String FROM_NOTIFICATION_TOKEN = "notify";
public static final String NOTIF_FLAGS_TOKEN = "notif_flags"; public static final String NOTIF_FLAGS_TOKEN = "notif_flags";
public static final String NOTIF_REPEAT_TOKEN = "notif_repeat";
// properties of the alarm that was triggered
private long repeatInterval = 0;
private int flags = 0;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras(); Bundle extras = getIntent().getExtras();
if(extras != null && extras.containsKey(FROM_NOTIFICATION_TOKEN)) if(extras != null && extras.containsKey(FROM_NOTIFICATION_TOKEN)) {
if(extras.containsKey(NOTIF_REPEAT_TOKEN))
repeatInterval = extras.getLong(NOTIF_REPEAT_TOKEN);
if(extras.containsKey(NOTIF_FLAGS_TOKEN))
flags = extras.getInt(NOTIF_FLAGS_TOKEN);
showNotificationAlert(); showNotificationAlert();
} }
}
/** Called when user clicks on a notification to get here */ /** Called when user clicks on a notification to get here */
private void showNotificationAlert() { private void showNotificationAlert() {
@ -75,7 +85,8 @@ public class TaskViewNotifier extends TaskView {
@Override @Override
public void onNumberPicked(NumberPicker view, int number) { public void onNumberPicked(NumberPicker view, int number) {
Notifications.createSnoozeAlarm(TaskViewNotifier.this, Notifications.createSnoozeAlarm(TaskViewNotifier.this,
model.getTaskIdentifier(), number * 60); model.getTaskIdentifier(), number * 60, flags,
repeatInterval);
setResult(Constants.RESULT_GO_HOME); setResult(Constants.RESULT_GO_HOME);
TaskList.shouldCloseInstance = true; TaskList.shouldCloseInstance = true;

@ -23,7 +23,6 @@ import java.util.Date;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import android.app.Activity;
import android.content.ContentValues; import android.content.ContentValues;
import android.content.Context; import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
@ -47,14 +46,14 @@ public class AlertController extends AbstractController {
return cursor; return cursor;
} }
/** Get a list of tag identifiers for the given task */ /** Get a list of tag identifiers for the given task */
public List<Date> getTaskAlerts(Activity activity, TaskIdentifier public List<Date> getTaskAlerts(TaskIdentifier
taskId) throws SQLException { taskId) throws SQLException {
List<Date> list = new LinkedList<Date>(); List<Date> list = new LinkedList<Date>();
Cursor cursor = alertDatabase.query(ALERT_TABLE_NAME, Cursor cursor = alertDatabase.query(ALERT_TABLE_NAME,
Alert.FIELD_LIST, Alert.TASK + " = ?", Alert.FIELD_LIST, Alert.TASK + " = ?",
new String[] { taskId.idAsString() }, null, null, null); new String[] { taskId.idAsString() }, null, null, null);
activity.startManagingCursor(cursor);
try {
if(cursor.getCount() == 0) if(cursor.getCount() == 0)
return list; return list;
do { do {
@ -63,6 +62,9 @@ public class AlertController extends AbstractController {
} while(!cursor.isLast()); } while(!cursor.isLast());
return list; return list;
} finally {
cursor.close();
}
} }
/** Remove all alerts from the task */ /** Remove all alerts from the task */

@ -192,7 +192,7 @@ public class TaskController extends AbstractController {
TaskModelForRepeat repeatModel = new TaskModelForRepeat(cursor, values); TaskModelForRepeat repeatModel = new TaskModelForRepeat(cursor, values);
RepeatInfo repeatInfo = repeatModel.getRepeat(); RepeatInfo repeatInfo = repeatModel.getRepeat();
if(repeatInfo != null) if(repeatInfo != null)
repeatModel.repeatTaskBy(repeatInfo); repeatModel.repeatTaskBy(context, this, repeatInfo);
cursor.close(); cursor.close();
} }

@ -20,16 +20,21 @@
package com.timsu.astrid.data.task; package com.timsu.astrid.data.task;
import java.util.Date; import java.util.Date;
import java.util.List;
import android.content.ContentValues; import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
import com.timsu.astrid.data.AbstractController; import com.timsu.astrid.data.AbstractController;
import com.timsu.astrid.data.alerts.AlertController;
import com.timsu.astrid.utilities.Notifications;
import com.timsu.astrid.utilities.Notifications.Notifiable;
/** Fields that you would want to edit pertaining to repeats */ /** Fields that you would want to edit pertaining to repeats */
public class TaskModelForRepeat extends AbstractTaskModel { public class TaskModelForRepeat extends AbstractTaskModel implements Notifiable {
static String[] FIELD_LIST = new String[] { static String[] FIELD_LIST = new String[] {
AbstractController.KEY_ROWID, AbstractController.KEY_ROWID,
@ -38,9 +43,14 @@ public class TaskModelForRepeat extends AbstractTaskModel {
PREFERRED_DUE_DATE, PREFERRED_DUE_DATE,
HIDDEN_UNTIL, HIDDEN_UNTIL,
PROGRESS_PERCENTAGE, PROGRESS_PERCENTAGE,
ESTIMATED_SECONDS,
LAST_NOTIFIED,
NOTIFICATIONS,
NOTIFICATION_FLAGS,
}; };
public void repeatTaskBy(RepeatInfo repeatInfo) { public void repeatTaskBy(Context context, TaskController taskController,
RepeatInfo repeatInfo) {
if(getDefiniteDueDate() != null) if(getDefiniteDueDate() != null)
setDefiniteDueDate(repeatInfo.shiftDate(getDefiniteDueDate())); setDefiniteDueDate(repeatInfo.shiftDate(getDefiniteDueDate()));
if(getHiddenUntil() != null) if(getHiddenUntil() != null)
@ -49,7 +59,18 @@ public class TaskModelForRepeat extends AbstractTaskModel {
setPreferredDueDate(repeatInfo.shiftDate(getPreferredDueDate())); setPreferredDueDate(repeatInfo.shiftDate(getPreferredDueDate()));
setProgressPercentage(0); setProgressPercentage(0);
// TODO shift fixed alerts? // shift fixed alerts?
AlertController alertController = new AlertController(context);
alertController.open();
List<Date> alerts = alertController.getTaskAlerts(getTaskIdentifier());
alertController.removeAlerts(getTaskIdentifier());
for(int i = 0; i < alerts.size(); i++) {
Date newAlert = repeatInfo.shiftDate(alerts.get(i));
alertController.addAlert(getTaskIdentifier(), newAlert);
alerts.set(i, newAlert);
}
Notifications.updateAlarm(context, taskController, alertController, this);
alertController.close();
} }
// --- constructors // --- constructors
@ -66,6 +87,45 @@ public class TaskModelForRepeat extends AbstractTaskModel {
return super.getRepeat(); return super.getRepeat();
} }
@Override
public Integer getNotificationIntervalSeconds() {
return super.getNotificationIntervalSeconds();
}
@Override
public boolean isTaskCompleted() {
return super.isTaskCompleted();
}
@Override
public Date getDefiniteDueDate() {
return super.getDefiniteDueDate();
}
@Override
public Integer getEstimatedSeconds() {
return super.getEstimatedSeconds();
}
@Override
public Date getHiddenUntil() {
return super.getHiddenUntil();
}
@Override
public Date getPreferredDueDate() {
return super.getPreferredDueDate();
}
@Override
public int getNotificationFlags() {
return super.getNotificationFlags();
}
@Override
public Date getLastNotificationDate() {
return super.getLastNotificationDate();
}
@Override @Override
public void setDefiniteDueDate(Date definiteDueDate) { public void setDefiniteDueDate(Date definiteDueDate) {
super.setDefiniteDueDate(definiteDueDate); super.setDefiniteDueDate(definiteDueDate);
@ -80,4 +140,5 @@ public class TaskModelForRepeat extends AbstractTaskModel {
public void setHiddenUntil(Date hiddenUntil) { public void setHiddenUntil(Date hiddenUntil) {
super.setHiddenUntil(hiddenUntil); super.setHiddenUntil(hiddenUntil);
} }
} }

@ -13,13 +13,11 @@ import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.res.Resources; import android.content.res.Resources;
import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.util.Log; import android.util.Log;
import com.timsu.astrid.R; import com.timsu.astrid.R;
import com.timsu.astrid.activities.TaskViewNotifier; import com.timsu.astrid.activities.TaskViewNotifier;
import com.timsu.astrid.data.alerts.Alert;
import com.timsu.astrid.data.alerts.AlertController; import com.timsu.astrid.data.alerts.AlertController;
import com.timsu.astrid.data.task.TaskController; import com.timsu.astrid.data.task.TaskController;
import com.timsu.astrid.data.task.TaskIdentifier; import com.timsu.astrid.data.task.TaskIdentifier;
@ -30,6 +28,7 @@ public class Notifications extends BroadcastReceiver {
private static final String ID_KEY = "id"; private static final String ID_KEY = "id";
private static final String FLAGS_KEY = "flags"; private static final String FLAGS_KEY = "flags";
private static final String REPEAT_KEY = "repeat";
// stuff for scheduling // stuff for scheduling
/** minimum # of seconds before a deadline to notify */ /** minimum # of seconds before a deadline to notify */
@ -78,7 +77,9 @@ public class Notifications extends BroadcastReceiver {
else else
reminder = getRandomReminder(r); reminder = getRandomReminder(r);
if(!showNotification(context, id, flags, reminder)) { long repeatInterval = intent.getLongExtra(REPEAT_KEY, 0);
if(!showNotification(context, id, flags, repeatInterval, reminder)) {
deleteAlarm(context, id); deleteAlarm(context, id);
NotificationManager nm = (NotificationManager) NotificationManager nm = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE); context.getSystemService(Context.NOTIFICATION_SERVICE);
@ -164,19 +165,22 @@ public class Notifications extends BroadcastReceiver {
} }
// fixed alerts // fixed alerts
Cursor cursor = alertController.getTaskAlertsCursor(task.getTaskIdentifier()); List<Date> alerts = alertController.getTaskAlerts(task.getTaskIdentifier());
Date currentDate = new Date(); scheduleFixedAlerts(context, task.getTaskIdentifier(), alerts);
}
/** Schedule a list of alerts for a task */
public static void scheduleFixedAlerts(Context context, TaskIdentifier taskId,
List<Date> alerts) {
int alertId = 0; int alertId = 0;
while(cursor.getCount() > 0 && !cursor.isLast()) { Date currentDate = new Date();
cursor.moveToNext(); for(Date alert : alerts) {
Date alert = new Alert(cursor).getDate();
if(alert.before(currentDate)) if(alert.before(currentDate))
continue; continue;
scheduleAlarm(context, task.getTaskIdentifier().getId(), scheduleAlarm(context, taskId.getId(),
alert.getTime(), FLAG_FIXED | (alertId++ << FIXED_ID_SHIFT)); alert.getTime(), FLAG_FIXED | (alertId++ << FIXED_ID_SHIFT));
} }
cursor.close();
} }
/** Schedule an alert around a deadline /** Schedule an alert around a deadline
@ -206,29 +210,39 @@ public class Notifications extends BroadcastReceiver {
/** Create a 'snooze' reminder for this task */ /** Create a 'snooze' reminder for this task */
public static void createSnoozeAlarm(Context context, TaskIdentifier id, public static void createSnoozeAlarm(Context context, TaskIdentifier id,
int secondsToSnooze) { int secondsToSnooze, int flags, long repeatInterval) {
// if this is a one-off alarm, just schedule a snooze-type alarm
if(repeatInterval == 0)
scheduleAlarm(context, id.getId(), System.currentTimeMillis() + scheduleAlarm(context, id.getId(), System.currentTimeMillis() +
secondsToSnooze * 1000, FLAG_SNOOZE); secondsToSnooze * 1000, FLAG_SNOOZE);
// else, reschedule our normal alarm
else
scheduleRepeatingAlarm(context, id.getId(), System.currentTimeMillis() +
secondsToSnooze * 1000, flags, repeatInterval);
} }
/** Helper method to create a PendingIntent from an ID & flags */ /** Helper method to create a Intent for alarm from an ID & flags */
private static PendingIntent createPendingIntent(Context context, private static Intent createAlarmIntent(Context context, long id, int flags) {
long id, int flags) {
Intent intent = new Intent(context, Notifications.class); Intent intent = new Intent(context, Notifications.class);
intent.setType(Long.toString(id)); intent.setType(Long.toString(id));
intent.setAction(Integer.toString(flags)); intent.setAction(Integer.toString(flags));
intent.putExtra(ID_KEY, id); intent.putExtra(ID_KEY, id);
intent.putExtra(FLAGS_KEY, flags); intent.putExtra(FLAGS_KEY, flags);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
return sender; return intent;
} }
/** Delete the given alarm */ /** Delete the given alarm */
public static void deleteAlarm(Context context, long id) { public static void deleteAlarm(Context context, long id) {
AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
am.cancel(createPendingIntent(context, id, 0)); // clear all possible alarms
for(int flag = 0; flag < (6 << FIXED_ID_SHIFT); flag++) {
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
createAlarmIntent(context, id, flag), 0);
am.cancel(pendingIntent);
}
// clear current notifications too // clear current notifications too
clearAllNotifications(context, new TaskIdentifier(id)); clearAllNotifications(context, new TaskIdentifier(id));
@ -238,9 +252,11 @@ public class Notifications extends BroadcastReceiver {
public static void scheduleAlarm(Context context, long id, long when, public static void scheduleAlarm(Context context, long id, long when,
int flags) { int flags) {
AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
createAlarmIntent(context, id, flags), 0);
Log.e("Astrid", "Alarm set for " + new Date(when)); Log.e("Astrid", "Alarm (" + id + ", " + flags + ") set for " + new Date(when));
am.set(AlarmManager.RTC_WAKEUP, when, createPendingIntent(context, id, flags)); am.set(AlarmManager.RTC_WAKEUP, when, pendingIntent);
} }
/** Schedules a recurring alarm for a single task */ /** Schedules a recurring alarm for a single task */
@ -250,10 +266,14 @@ public class Notifications extends BroadcastReceiver {
return; return;
AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent alarmIntent = createAlarmIntent(context, id, flags);
Log.e("Astrid", "Alarm set for " + new Date(when) + " every " + interval/1000 + " s"); alarmIntent.putExtra(REPEAT_KEY, interval);
am.setRepeating(AlarmManager.RTC_WAKEUP, when, interval, PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
createPendingIntent(context, id, flags)); alarmIntent, 0);
Log.e("Astrid", "Alarm (" + id + ", " + flags + ") set for " +
new Date(when) + " every " + interval/1000 + " s");
am.setRepeating(AlarmManager.RTC_WAKEUP, when, interval, pendingIntent);
} }
// --- notification manager stuff // --- notification manager stuff
@ -275,7 +295,7 @@ public class Notifications extends BroadcastReceiver {
/** Schedule a new notification about the given task. Returns false if there was /** Schedule a new notification about the given task. Returns false if there was
* some sort of error or the alarm should be disabled. */ * some sort of error or the alarm should be disabled. */
public static boolean showNotification(Context context, long id, public static boolean showNotification(Context context, long id,
int flags, String reminder) { int flags, long repeatInterval, String reminder) {
String taskName; String taskName;
TaskController controller = new TaskController(context); TaskController controller = new TaskController(context);
@ -336,6 +356,7 @@ public class Notifications extends BroadcastReceiver {
notifyIntent.putExtra(TaskViewNotifier.LOAD_INSTANCE_TOKEN, id); notifyIntent.putExtra(TaskViewNotifier.LOAD_INSTANCE_TOKEN, id);
notifyIntent.putExtra(TaskViewNotifier.FROM_NOTIFICATION_TOKEN, true); notifyIntent.putExtra(TaskViewNotifier.FROM_NOTIFICATION_TOKEN, true);
notifyIntent.putExtra(TaskViewNotifier.NOTIF_FLAGS_TOKEN, flags); notifyIntent.putExtra(TaskViewNotifier.NOTIF_FLAGS_TOKEN, flags);
notifyIntent.putExtra(TaskViewNotifier.NOTIF_REPEAT_TOKEN, repeatInterval);
PendingIntent pendingIntent = PendingIntent.getActivity(context, PendingIntent pendingIntent = PendingIntent.getActivity(context,
(int)id, notifyIntent, PendingIntent.FLAG_ONE_SHOT); (int)id, notifyIntent, PendingIntent.FLAG_ONE_SHOT);

Loading…
Cancel
Save