mirror of https://github.com/tasks/tasks
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
186 lines
6.3 KiB
Java
186 lines
6.3 KiB
Java
package com.todoroo.astrid.alarms;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Date;
|
|
import java.util.LinkedHashSet;
|
|
|
|
import android.app.AlarmManager;
|
|
import android.app.PendingIntent;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.util.Log;
|
|
|
|
import com.todoroo.andlib.data.TodorooCursor;
|
|
import com.todoroo.andlib.service.ContextManager;
|
|
import com.todoroo.andlib.sql.Criterion;
|
|
import com.todoroo.andlib.sql.Join;
|
|
import com.todoroo.andlib.sql.Order;
|
|
import com.todoroo.andlib.sql.Query;
|
|
import com.todoroo.andlib.utility.DateUtilities;
|
|
import com.todoroo.astrid.core.PluginServices;
|
|
import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria;
|
|
import com.todoroo.astrid.dao.TaskDao.TaskCriteria;
|
|
import com.todoroo.astrid.data.Metadata;
|
|
import com.todoroo.astrid.data.Task;
|
|
import com.todoroo.astrid.reminders.Notifications;
|
|
import com.todoroo.astrid.reminders.ReminderService;
|
|
import com.todoroo.astrid.service.MetadataService;
|
|
import com.todoroo.astrid.utility.Constants;
|
|
|
|
/**
|
|
* Provides operations for working with alerts
|
|
*
|
|
* @author Tim Su <tim@todoroo.com>
|
|
*
|
|
*/
|
|
public class AlarmService {
|
|
|
|
// --- singleton
|
|
|
|
private static AlarmService instance = null;
|
|
|
|
public static synchronized AlarmService getInstance() {
|
|
if(instance == null)
|
|
instance = new AlarmService();
|
|
return instance;
|
|
}
|
|
|
|
// --- data retrieval
|
|
|
|
public static final String IDENTIFIER = "alarms"; //$NON-NLS-1$
|
|
|
|
/**
|
|
* Return alarms for the given task. PLEASE CLOSE THE CURSOR!
|
|
*
|
|
* @param taskId
|
|
*/
|
|
public TodorooCursor<Metadata> getAlarms(long taskId) {
|
|
return PluginServices.getMetadataService().query(Query.select(
|
|
Metadata.PROPERTIES).where(MetadataCriteria.byTaskAndwithKey(
|
|
taskId, AlarmFields.METADATA_KEY)).orderBy(Order.asc(AlarmFields.TIME)));
|
|
}
|
|
|
|
/**
|
|
* Save the given array of alarms into the database
|
|
* @param taskId
|
|
* @param tags
|
|
* @return true if data was changed
|
|
*/
|
|
public boolean synchronizeAlarms(long taskId, LinkedHashSet<Long> alarms) {
|
|
MetadataService service = PluginServices.getMetadataService();
|
|
|
|
ArrayList<Metadata> metadata = new ArrayList<Metadata>();
|
|
for(Long alarm : alarms) {
|
|
Metadata item = new Metadata();
|
|
item.setValue(Metadata.KEY, AlarmFields.METADATA_KEY);
|
|
item.setValue(AlarmFields.TIME, alarm);
|
|
item.setValue(AlarmFields.TYPE, AlarmFields.TYPE_SINGLE);
|
|
metadata.add(item);
|
|
}
|
|
|
|
boolean changed = service.synchronizeMetadata(taskId, metadata, Metadata.KEY.eq(AlarmFields.METADATA_KEY));
|
|
if(changed)
|
|
scheduleAlarms(taskId);
|
|
return changed;
|
|
}
|
|
|
|
// --- alarm scheduling
|
|
|
|
/**
|
|
* Gets a listing of all alarms that are active
|
|
* @param properties
|
|
* @return todoroo cursor. PLEASE CLOSE THIS CURSOR!
|
|
*/
|
|
private TodorooCursor<Metadata> getActiveAlarms() {
|
|
return PluginServices.getMetadataService().query(Query.select(Metadata.ID, Metadata.TASK, AlarmFields.TIME).
|
|
join(Join.inner(Task.TABLE, Metadata.TASK.eq(Task.ID))).
|
|
where(Criterion.and(TaskCriteria.isActive(), MetadataCriteria.withKey(AlarmFields.METADATA_KEY))));
|
|
}
|
|
|
|
/**
|
|
* Gets a listing of alarms by task
|
|
* @param properties
|
|
* @return todoroo cursor. PLEASE CLOSE THIS CURSOR!
|
|
*/
|
|
private TodorooCursor<Metadata> getActiveAlarmsForTask(long taskId) {
|
|
return PluginServices.getMetadataService().query(Query.select(Metadata.ID, Metadata.TASK, AlarmFields.TIME).
|
|
join(Join.inner(Task.TABLE, Metadata.TASK.eq(Task.ID))).
|
|
where(Criterion.and(TaskCriteria.isActive(),
|
|
MetadataCriteria.byTaskAndwithKey(taskId, AlarmFields.METADATA_KEY))));
|
|
}
|
|
|
|
/**
|
|
* Schedules all alarms
|
|
*/
|
|
public void scheduleAllAlarms() {
|
|
TodorooCursor<Metadata> cursor = getActiveAlarms();
|
|
try {
|
|
Metadata alarm = new Metadata();
|
|
for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
|
|
alarm.readFromCursor(cursor);
|
|
scheduleAlarm(alarm);
|
|
}
|
|
} catch (Exception e) {
|
|
// suppress
|
|
} finally {
|
|
cursor.close();
|
|
}
|
|
}
|
|
|
|
private static final long NO_ALARM = Long.MAX_VALUE;
|
|
|
|
/**
|
|
* Schedules alarms for a single task
|
|
* @param task
|
|
*/
|
|
public void scheduleAlarms(long taskId) {
|
|
TodorooCursor<Metadata> cursor = getActiveAlarmsForTask(taskId);
|
|
try {
|
|
Metadata alarm = new Metadata();
|
|
for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
|
|
alarm.readFromCursor(cursor);
|
|
scheduleAlarm(alarm);
|
|
}
|
|
} catch (Exception e) {
|
|
Log.i("astrid-alarms", "Error scheduling alarm", e); //$NON-NLS-1$ //$NON-NLS-2$
|
|
} finally {
|
|
cursor.close();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Schedules alarms for a single task
|
|
*
|
|
* @param shouldPerformPropertyCheck
|
|
* whether to check if task has requisite properties
|
|
*/
|
|
@SuppressWarnings("nls")
|
|
private void scheduleAlarm(Metadata alarm) {
|
|
if(alarm == null)
|
|
return;
|
|
|
|
long taskId = alarm.getValue(Metadata.TASK);
|
|
int type = ReminderService.TYPE_ALARM;
|
|
|
|
Context context = ContextManager.getContext();
|
|
Intent intent = new Intent(context, Notifications.class);
|
|
intent.setAction("ALARM" + alarm.getId()); //$NON-NLS-1$
|
|
intent.putExtra(Notifications.ID_KEY, taskId);
|
|
intent.putExtra(Notifications.TYPE_KEY, type);
|
|
|
|
AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
|
|
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, (int)alarm.getId(),
|
|
intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
|
|
|
long time = alarm.getValue(AlarmFields.TIME);
|
|
if(time == 0 || time == NO_ALARM)
|
|
am.cancel(pendingIntent);
|
|
else if(time > DateUtilities.now()) {
|
|
if(Constants.DEBUG)
|
|
Log.e("Astrid", "Alarm (" + taskId + ", " + type +
|
|
", " + alarm.getId() + ") set for " + new Date(time));
|
|
am.set(AlarmManager.RTC_WAKEUP, time, pendingIntent);
|
|
}
|
|
}
|
|
}
|