Search code examples
androidsqlitealarmmanagerandroid-broadcast

Android: Reminder concept with Alarm Manager


I tried to make reminder application for Android, followed tutorial from this website Set Notification for Specific Date. Basically it used Alarm Manager to create a reminder.

This code used to call alarm manager and show notification on specific date.

reminderClient.setAlarmForNotification(calendar, uniqueid, interval);

I save all of the reminder in SQLite Database. So when this code (above) called, new record will be inserted to database and when notification show up, that record will be deleted.

The problem is whenever device restart, alarm manager stopped.

So I create a new BroadcastReceiver that receive event when device turned on.

<application ...  >

    <receiver android:name=".ReminderReceiver" >
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <uses-permission android:name="android.permission.WAKE_LOCK" />
        </intent-filter>
    </receiver>
</application>

public class ReminderReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        //do stuff
    }

}

Is it OK to get all record from database, and call setAlarmForNotification again inside OnReceive like this?

public class ReminderReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        List<MyReminder> reminders = database.getAllReminder();
        Calendar cal = Calendar.getInstance();

        for (int i=0; i<reminders.size(); i++) {
            cal.setTime(parseStringDateToDate(reminders.get(i).getDateTime());

            reminderClient.setAlarmForNotification(
                cal, 
                reminders.get(i).getUniqueID(), 
                reminders.get(i).getInterval()
            );
        }
    }

}

Or is there a better way?


Solution

  • BroadcastReceiver's onReceive() is called on UI thread so in common case it's not right to access a database or do any other file I/O in this method. For this task you need two things: background thread to give the system an ability to make its stuff in parallel and a Service to tell the system that it should not kill your process when onReceive() is finished. There is a component that gives you both things - IntentService. It's a Service and a working thread that finishes and stops a Service when return from onHandleIntent().

    Also posibly you will need a WakeLock to ensure that all your calculations are finished and alarms are properly set. Look at WakefulBroadcastReceiver that is written just for this case.

    NOTE: Actually in your case file I/O is really minimal and system boot probably is not a moment when every hundred milliseconds are crucial. But there is really no reason not to do things right.