Skip to content

Commit 84f8403

Browse files
author
tobias
committed
- added support for multiple alarm notifications at the same time
1 parent 7378723 commit 84f8403

File tree

3 files changed

+80
-19
lines changed

3 files changed

+80
-19
lines changed

project.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@
1111
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
1212

1313
# Project target.
14-
target=android-16
14+
target=android-19
1515
android.library=true

src/org/dmfs/provider/tasks/TaskProvider.java

+14-1
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,11 @@ public int deleteInTransaction(Uri uri, String selection, String[] selectionArgs
546546
values.put(TaskSyncColumns._DELETED, true);
547547
values.put(CommonSyncColumns._DIRTY, true);
548548
count = db.update(Tables.TASKS, values, selection, selectionArgs);
549+
550+
// update alarms
551+
AlarmNotificationHandler alarmHandler = new AlarmNotificationHandler(getContext());
552+
alarmHandler.setUpcomingDueAlarm(mDb, System.currentTimeMillis());
553+
549554
}
550555
break;
551556
case CATEGORIES:
@@ -625,7 +630,7 @@ public Uri insertInTransaction(Uri uri, ContentValues values, boolean isSyncAdap
625630

626631
// update alarms
627632
AlarmNotificationHandler alarmHandler = new AlarmNotificationHandler(getContext());
628-
alarmHandler.setUpcomingDueAlarm(mDb);
633+
alarmHandler.setUpcomingDueAlarm(mDb, System.currentTimeMillis());
629634
break;
630635

631636
case CATEGORIES:
@@ -685,6 +690,10 @@ public int updateInTransaction(Uri uri, ContentValues values, String selection,
685690
// update related instances
686691
updateInstancesOfAllTasks(db, values, selection, selectionArgs);
687692

693+
// update alarms
694+
AlarmNotificationHandler alarmHandler = new AlarmNotificationHandler(getContext());
695+
alarmHandler.setUpcomingDueAlarm(mDb, System.currentTimeMillis());
696+
688697
break;
689698
case TASK_ID:
690699
String newSelection = updateSelection(selectId(uri), selection);
@@ -700,6 +709,10 @@ public int updateInTransaction(Uri uri, ContentValues values, String selection,
700709
count = db.update(Tables.TASKS, values, newSelection, selectionArgs);
701710
String taskSelection = updateSelection(selectTaskId(uri), selection).toString();
702711
updateInstancesOfOneTask(db, getId(uri), values, taskSelection, selectionArgs);
712+
713+
// update alarms
714+
AlarmNotificationHandler taskAlarmHandler = new AlarmNotificationHandler(getContext());
715+
taskAlarmHandler.setUpcomingDueAlarm(mDb, System.currentTimeMillis());
703716
break;
704717
case CATEGORIES:
705718
break;

src/org/dmfs/provider/tasks/handler/AlarmNotificationHandler.java

+65-17
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import org.dmfs.provider.tasks.TaskDatabaseHelper.Tables;
88
import org.dmfs.provider.tasks.TaskProvider;
99

10+
import android.annotation.TargetApi;
1011
import android.app.AlarmManager;
1112
import android.app.PendingIntent;
1213
import android.content.BroadcastReceiver;
@@ -15,6 +16,7 @@
1516
import android.database.Cursor;
1617
import android.database.sqlite.SQLiteDatabase;
1718
import android.database.sqlite.SQLiteOpenHelper;
19+
import android.os.Build;
1820

1921

2022
/**
@@ -64,25 +66,33 @@ public AlarmNotificationHandler(Context context)
6466
*
6567
* @param taskId
6668
* The row id of the task to set an alarm for.
67-
* @param dueDate
69+
* @param dueTime
6870
* The date in milliseconds when the task is due.
6971
* @param taskTitle
7072
* The title of the task.
7173
*/
72-
public void setDueAlarm(long taskId, long dueDate, String taskTitle)
74+
@TargetApi(19)
75+
public void setDueAlarm(long taskId, long dueTime, String taskTitle)
7376
{
7477
Context context = mContext.get();
7578
if (context != null)
7679
{
7780
Intent intentAlarm = new Intent(context, AlarmNotificationHandler.class);
7881
intentAlarm.putExtra(EXTRA_TASK_ID, taskId);
79-
intentAlarm.putExtra(EXTRA_TASK_DUE_TIME, dueDate);
82+
intentAlarm.putExtra(EXTRA_TASK_DUE_TIME, dueTime);
8083
intentAlarm.putExtra(EXTRA_TASK_TITLE, taskTitle);
81-
8284
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, REQUEST_CODE_DUE_ALARM, intentAlarm, PendingIntent.FLAG_UPDATE_CURRENT);
83-
mAlarmManager.set(AlarmManager.RTC_WAKEUP, dueDate, pendingIntent);
84-
}
8585

86+
// AlarmManager API changed in v19 (KitKat) and the "set" method is not called at the exact time anymore
87+
if (Build.VERSION.SDK_INT > 18)
88+
{
89+
mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, dueTime, pendingIntent);
90+
}
91+
else
92+
{
93+
mAlarmManager.set(AlarmManager.RTC_WAKEUP, dueTime, pendingIntent);
94+
}
95+
}
8696
}
8797

8898

@@ -91,20 +101,25 @@ public void setDueAlarm(long taskId, long dueDate, String taskTitle)
91101
*
92102
* @param db
93103
* The {@link SQLiteDatabase}.
104+
* @param time
105+
* The absolute minimum time in milliseconds when the next alarm can be due.
106+
*
94107
*/
95-
public void setUpcomingDueAlarm(SQLiteDatabase db)
108+
public void setUpcomingDueAlarm(SQLiteDatabase db, long time)
96109
{
97110
mDb = db;
98111
String[] projection = new String[] { Instances.TASK_ID, Instances.INSTANCE_DUE, Tasks.TITLE };
99-
String selection = System.currentTimeMillis() + " <= " + Instances.INSTANCE_DUE;
112+
String selection = time + " <= " + Instances.INSTANCE_DUE;
100113
Cursor cursor = db.query(Tables.INSTANCE_VIEW, projection, selection, null, null, null, Instances.INSTANCE_DUE, "1");
101114

102115
if (cursor != null)
103116
{
104117
try
105118
{
106-
cursor.moveToFirst();
107-
setDueAlarm(cursor.getLong(0), cursor.getLong(1), cursor.getString(2));
119+
if (cursor.moveToFirst())
120+
{
121+
setDueAlarm(cursor.getLong(0), cursor.getLong(1), cursor.getString(2));
122+
}
108123
}
109124
finally
110125
{
@@ -120,25 +135,58 @@ public void setUpcomingDueAlarm(SQLiteDatabase db)
120135
@Override
121136
public void onReceive(Context context, Intent intent)
122137
{
138+
mContext = new SoftReference<Context>(context);
139+
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
123140
if (intent.hasExtra(EXTRA_TASK_ID))
124141
{
125-
// Alarm went off -> inform the application
126-
mContext = new SoftReference<Context>(context);
127-
sendTaskDueAlarmBroadcast(intent.getLongExtra(EXTRA_TASK_ID, 0), intent.getLongExtra(EXTRA_TASK_DUE_TIME, System.currentTimeMillis()),
128-
intent.getStringExtra(EXTRA_TASK_TITLE));
129142

130-
if (mDb != null)
143+
SQLiteDatabase db;
144+
if (mDb == null)
145+
{
146+
SQLiteOpenHelper dBHelper = new TaskProvider().getDatabaseHelper(context);
147+
db = dBHelper.getReadableDatabase();
148+
mDb = db;
149+
}
150+
151+
// check for all tasks which are due since the due alarm was set plus 1 second
152+
long currentDueTime = intent.getExtras().getLong(EXTRA_TASK_DUE_TIME);
153+
long nextDueTime = currentDueTime + 1000;
154+
String[] projection = new String[] { Instances.TASK_ID, Instances.INSTANCE_DUE, Tasks.TITLE };
155+
String selection = nextDueTime + " > " + Instances.INSTANCE_DUE + " AND " + currentDueTime + " <= " + Instances.INSTANCE_DUE;
156+
Cursor cursor = mDb.query(Tables.INSTANCE_VIEW, projection, selection, null, null, null, Instances.INSTANCE_DUE);
157+
158+
if (cursor != null)
131159
{
132-
setUpcomingDueAlarm(mDb);
160+
try
161+
{
162+
if (cursor.moveToFirst())
163+
{
164+
while (!cursor.isAfterLast())
165+
{
166+
// inform the application
167+
sendTaskDueAlarmBroadcast(cursor.getLong(0), cursor.getLong(1), cursor.getString(2));
168+
cursor.moveToNext();
169+
}
170+
171+
}
172+
}
173+
finally
174+
{
175+
cursor.close();
176+
}
133177
}
178+
// Set the next alarm
179+
setUpcomingDueAlarm(mDb, nextDueTime);
180+
mDb.close();
134181
}
135182
else if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
136183
{
137184
// device booted -> set upcoming alarm
138185
mContext = new SoftReference<Context>(context);
186+
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
139187
SQLiteOpenHelper dBHelper = new TaskProvider().getDatabaseHelper(context);
140188
SQLiteDatabase db = dBHelper.getReadableDatabase();
141-
setUpcomingDueAlarm(db);
189+
setUpcomingDueAlarm(db, System.currentTimeMillis());
142190
db.close();
143191

144192
}

0 commit comments

Comments
 (0)