Reminding the User with AlarmManager

297

Chapter 13: Reminding the User with AlarmManager

LOCK_NAME_STATIC; ➝ 12 lockStatic.setReferenceCountedtrue; ➝ 13 } returnlockStatic; ➝ 15 } public WakeReminderIntentServiceString name { ➝ 18 supername; } Override final protected void onHandleIntentIntent intent { ➝ 23 try { doReminderWorkintent; ➝ 25 } finally { getLockthis.release; ➝ 27 } } } Each numbered line is explained as follows: ➝ 2 This abstract method is implemented in any children of this class — such as in the child ReminderService as shown on line 7 of Listing 13-4. ➝ 3 This is the tag name of the lock that I will use to acquire the CPU lock. This tag name assists in debugging. ➝ 4 This is the private static wake lock variable, which is referenced and set later in this class. ➝ 5 This calls the getLock method, as described on line 8. After that call is returned, the acquire method is called to ensure that the device is on in the state that you requested, a partial wake lock. This wake lock prevents the device from sleeping, but it doesn’t turn on the screen. ➝ 8 This line defines the getLock method that returns the Power- Manager.WakeLock, which lets you inform Android that you would like the device to stay on to do some work. ➝ 10 This line retrieves the PowerManager from the getSystem- Service call. This is used to create the lock. ➝ 12 This creates a new WakeLock using the newWakeLock method call. This method accepts the following parameters: • flags: PowerManager.PARTIAL_WAKE_LOCK: You can provide numerous tags to this call; however, I am only providing this single tag. The PARTIAL_WAKE_LOCK tag informs Android that you need the CPU to be on, but the screen does not have to be on. 298 Part III: Creating a Feature-Rich Application • tag: LOCK_NAME_STATIC: The name of your class name or another string. This is used for debugging purposes. This is a custom string that is defined on line 3. ➝ 13 This line informs the PowerManager that this reference has been counted. ➝ 15 This returns the WakeLock to the caller. ➝ 18 This is the constructor with the name of the child instance that has created it. This name is used for debugging only. ➝ 23 This is the onHandleIntent call of the IntentService. As soon as the service is started, this method is called to handle the intent that was passed to it. ➝ 25 The service attempts to perform the necessary work by calling doReminderWork. ➝ 27 Regardless of whether the call to doReminderWork is success- ful, I want to make sure that I release the WakeLock. If I do not release the WakeLock, the device could be left in an On state until the phone is rebooted. This is very undesirable because it would drain the battery. This is why the release method is called in the final portion of the try-catch block. The final portion of the try-catch block is always called, regardless of whether the try succeeds or fails. Although no implementation for the doReminderWork exists in the ReminderService just yet, the Task Reminder application responds to alarms. Feel free to set up multiple tasks and to set break points in the debugger to watch the execution path break in the ReminderService doReminderWork method. The AlarmManager does not persist alarms. This means that if the device gets rebooted, the alarms must be set up again. Each time the phone is rebooted, the alarms need to be set up again. The previous code demonstrates what is necessary to perform work on a device that might be asleep or locked. This code acquires the wake lock, and while the device is locked into a wakeful state, I call into doReminder- Work, which is implemented in the ReminderService. Creating the ReminderService class The ReminderService class see Listing 13-4 is responsible for doing the work when an alarm is fired. The implementation in this chapter simply creates a shell for work to take place. I will be implementing the status bar notification in Chapter 14. 299

Chapter 13: Reminding the User with AlarmManager