1 00:00:08,880 --> 00:00:13,560 Hi, I'm Adam Porter, and this is Programming Mobile 2 00:00:13,560 --> 00:00:18,170 Applications for Android Handheld Systems. 3 00:00:19,210 --> 00:00:24,510 The example applications that we've studied up to now have made decisions 4 00:00:24,510 --> 00:00:29,350 and then taken action, now. But what 5 00:00:29,350 --> 00:00:33,990 if your application makes a decision, but wants to take an action an hour from 6 00:00:33,990 --> 00:00:38,440 now, tomorrow at midnight, or every 15 minutes from now on? 7 00:00:39,450 --> 00:00:45,140 In that case, your application will need to create and set alarms. 8 00:00:46,730 --> 00:00:51,500 In this lesson, I'll start by discussing what alarms are and how they're used. 9 00:00:52,510 --> 00:00:56,130 Next, I'll discuss the Android AlarmManager and 10 00:00:56,130 --> 00:00:59,150 the APIs it provides for setting and 11 00:00:59,150 --> 00:01:00,730 canceling alarms. 12 00:01:01,870 --> 00:01:06,950 After that, I'll discuss the various types of alarms that Android supports. 13 00:01:06,950 --> 00:01:12,500 And finally, I'll present and discuss an example application that uses alarms. 14 00:01:14,210 --> 00:01:19,480 Now in a nutshell, alarms are a mechanism for sending intents 15 00:01:19,480 --> 00:01:24,610 at some point, or points, in the future. And this is useful 16 00:01:24,610 --> 00:01:28,790 because it allows an application to cause some other code 17 00:01:28,790 --> 00:01:33,670 to execute even when that application is no longer running. 18 00:01:35,870 --> 00:01:39,530 Once alarms have been created and registered, they're retained 19 00:01:39,530 --> 00:01:43,580 and monitored even if the device goes to sleep. 20 00:01:43,580 --> 00:01:46,680 And as we'll talk about later, depending on how you configure 21 00:01:46,680 --> 00:01:51,000 an alarm, if it goes off while the device is sleeping, the 22 00:01:51,000 --> 00:01:54,640 device can be woken up to handle the alarm, or the 23 00:01:54,640 --> 00:01:58,470 alarm can be retained until the next time the device wakes up. 24 00:01:59,675 --> 00:02:00,890 And alarms will continue to 25 00:02:00,890 --> 00:02:04,430 be active until the device shuts down. 26 00:02:04,430 --> 00:02:08,140 On shutdown, all registered alarms will be canceled. 27 00:02:09,430 --> 00:02:10,690 [Alarm Examples] 28 00:02:10,690 --> 00:02:13,820 To give you some examples of alarms, the other day, I was digging 29 00:02:13,820 --> 00:02:16,230 through some Android source code and 30 00:02:16,230 --> 00:02:19,600 came across several applications that use alarms. 31 00:02:19,600 --> 00:02:23,390 For instance, the MMS messaging application uses 32 00:02:23,390 --> 00:02:26,260 alarms to start a service that can 33 00:02:26,260 --> 00:02:29,020 find MMS messages that haven't been delivered 34 00:02:29,020 --> 00:02:31,890 and can try again to deliver them. 35 00:02:31,890 --> 00:02:35,970 The Settings application can made a device discoverable 36 00:02:35,970 --> 00:02:37,270 over Bluetooth. 37 00:02:37,270 --> 00:02:42,600 And when it does this, that application sets an alarm, and when the 38 00:02:42,600 --> 00:02:47,920 alarm goes off, the application makes the device not discoverable anymore. 39 00:02:49,220 --> 00:02:52,830 And the Phone application keeps a cache of user information. 40 00:02:53,860 --> 00:02:58,350 This application uses alarms to periodically update that cache. 41 00:03:00,210 --> 00:03:01,330 If you want to use alarms 42 00:03:01,330 --> 00:03:06,930 in your own applications, you do so by interacting with the AlarmManager service. 43 00:03:08,220 --> 00:03:15,240 To get a reference to this service, you call the context classes GetSystemService, 44 00:03:15,240 --> 00:03:21,100 passing in the name of the service, in this case, Alarm_Service as a parameter. 45 00:03:23,800 --> 00:03:26,930 Once you have a reference to the AlarmManager, you can 46 00:03:26,930 --> 00:03:31,510 then use some of its methods to create and set alarms. 47 00:03:31,510 --> 00:03:37,330 For instance, you can use the Set method to set a single alarm. 48 00:03:37,330 --> 00:03:42,680 And this method has three parameters. A type, which we'll discuss shortly, a 49 00:03:42,680 --> 00:03:48,614 long, representing the time at which the alarm should go off and a PeningIntent, 50 00:03:48,614 --> 00:03:52,398 which encapsulates the operation that should occur 51 00:03:52,398 --> 00:03:55,612 when the alarm finally does go off. 52 00:03:55,962 --> 00:03:59,462 [Note: the following discussion applies to API Levels <= 18] 53 00:03:59,462 --> 00:04:03,407 Beginning with API 19 (KitKat) Alarm delivery is inexact] 54 00:04:03,407 --> 00:04:08,598 [See http://developer.android.com/reference/ android/app/AlarmManager.html] 55 00:04:08,751 --> 00:04:13,185 You can use this method, setRepeating, to set an alarm 56 00:04:13,185 --> 00:04:17,287 that repeatedly goes off at specific intervals. 57 00:04:17,509 --> 00:04:22,777 This method has four parameters: the three we saw in the Set method 58 00:04:22,777 --> 00:04:27,455 and an additional long that specifies the amount of time 59 00:04:27,455 --> 00:04:31,520 between each successive time that the alarm goes off. 60 00:04:33,570 --> 00:04:38,220 Another AlarmManager method is setInexactRepeating. 61 00:04:38,620 --> 00:04:44,445 This method is similar to setRepeating, in that the alarm should go off periodically, 62 00:04:45,100 --> 00:04:47,980 but this method gives Android more flexibility 63 00:04:47,980 --> 00:04:52,023 in deciding exactly when to fire the alarms. 64 00:04:52,420 --> 00:04:57,270 For instance, Android might batch up multiple alarms of this kind 65 00:04:57,760 --> 00:04:59,910 and fire them at the same time 66 00:05:00,436 --> 00:05:03,020 so as not to wake up the device too many times. 67 00:05:04,170 --> 00:05:07,980 And if you want to have this kind of behavior, then your time interval 68 00:05:07,980 --> 00:05:13,765 must be one of the following constants, which specifies intervals of 15 minutes, 69 00:05:14,425 --> 00:05:19,878 30 minutes, one hour, 12 hours, and 24 hours. 70 00:05:20,670 --> 00:05:24,400 If you don't use one of these constants, then the behavior of the alarms 71 00:05:24,400 --> 00:05:30,093 is the same thing that you would have gotten had you used setRepeating instead. 72 00:05:32,290 --> 00:05:37,102 Now each of the three methods I just showed you took a parameter called Type. 73 00:05:37,750 --> 00:05:39,383 Let's talk about alarm types now. 74 00:05:41,040 --> 00:05:46,030 Android provides two degrees of configurability with respect to alarms. 75 00:05:46,540 --> 00:05:52,590 One has to do with how time information is interpreted, and the other tells Android 76 00:05:52,590 --> 00:05:57,461 how to respond if the device is sleeping when the alarm fires. 77 00:05:58,080 --> 00:06:00,170 Let's look at each of these one at a time. 78 00:06:02,387 --> 00:06:07,310 First, you remember that each of the alarm setting methods took a long 79 00:06:07,310 --> 00:06:12,150 as a parameter, and I said that, that long represented a time. 80 00:06:13,300 --> 00:06:18,176 Android alarms can interpret this long value in two different ways. 81 00:06:18,570 --> 00:06:23,350 One: it can consider it to be a real or wall clock time, 82 00:06:23,373 --> 00:06:27,330 and in this case, the long represents the number of milliseconds 83 00:06:27,330 --> 00:06:30,899 since midnight January 1, 1970. 84 00:06:32,110 --> 00:06:37,750 And two: it can interpret it to be the system's up time, and that is, 85 00:06:37,750 --> 00:06:42,660 the amount of time since the time at which the system last booted up. 86 00:06:44,000 --> 00:06:48,480 The second issue is what should Android do if the alarm goes -- 87 00:06:48,480 --> 00:06:52,020 if, when the alarm goes off, the device is sleeping. 88 00:06:52,820 --> 00:06:56,810 One possibility is to wake up the device now, and deliver the intent. 89 00:06:57,780 --> 00:07:01,211 Another choice is to let the device continue sleeping, 90 00:07:01,620 --> 00:07:05,040 and to deliver the intent the next time the device wakes up. 91 00:07:06,760 --> 00:07:12,205 So, putting all those together, there are four possibilities, defined as follows. 92 00:07:12,205 --> 00:07:14,812 RTC_WAKEUP: 93 00:07:15,795 --> 00:07:18,683 fire the alarm at the specified wall clock time. 94 00:07:19,290 --> 00:07:24,160 If the device is asleep, wake it now and deliver the intent. 95 00:07:25,520 --> 00:07:26,718 RTC: 96 00:07:27,120 --> 00:07:31,870 Fire the alarm at the specified wall clock time, but if the device is asleep, 97 00:07:31,884 --> 00:07:33,357 don't wake it up now. 98 00:07:33,730 --> 00:07:38,305 Instead, deliver the intent when the device next wakes up. 99 00:07:39,840 --> 00:07:46,716 And there is ELAPSEDREALTIME and ELAPSEDREALTIME_WAKEUP. (add coment in Amara) 100 00:07:47,464 --> 00:07:51,210 For these two types of alarms, Android fires the alarm 101 00:07:51,210 --> 00:07:54,719 when the device has been up for the specified time, 102 00:07:55,333 --> 00:07:58,538 and if the device is sleeping when the alarm goes off, 103 00:07:58,805 --> 00:08:02,673 it will not be woken up with ELAPSED_REALTIME, 104 00:08:02,951 --> 00:08:08,727 it will be woken up with ELAPSEDREALTIMEWAKEUP. 105 00:08:10,007 --> 00:08:11,693 [PendingIntent] 106 00:08:11,693 --> 00:08:16,890 The last part of the AlarmManager APIs that we'll discuss is the PendingIntent. 107 00:08:17,980 --> 00:08:23,680 As we discussed back in user notifications, a PendingIntent holds a regular intent 108 00:08:23,686 --> 00:08:26,384 and essentially serves as a permission slip, 109 00:08:26,384 --> 00:08:30,265 in which one component allows a second component 110 00:08:30,265 --> 00:08:35,186 to use the underlying intent as if it were the first component. 111 00:08:35,974 --> 00:08:39,813 Three methods that can be used to create a PendingIntent are: 112 00:08:39,823 --> 00:08:45,710 getActivity, which returns a PendingIntent that can be used to start an activity, 113 00:08:46,550 --> 00:08:52,871 GetBroadcast, which returns a PendingIntent that can be used to broadcast an intent, 114 00:08:53,690 --> 00:08:56,902 and getService, which returns a PendingIntent 115 00:08:56,902 --> 00:08:59,660 that can be used to start a service. 116 00:09:01,220 --> 00:09:02,885 So now that we've learned about alarms, 117 00:09:02,885 --> 00:09:07,318 let's take a look at an example application called AlarmCreate. 118 00:09:07,880 --> 00:09:11,941 This application uses alarms to gently encourage a student 119 00:09:11,941 --> 00:09:16,309 to stop playing video games and return to his or her studies. 120 00:09:17,180 --> 00:09:18,110 Let's take a look. 121 00:09:23,199 --> 00:09:24,250 Here's my device. 122 00:09:26,420 --> 00:09:28,982 I'll now start up the AlarmCreate application. 123 00:09:31,260 --> 00:09:35,974 The application displays a simple user interface with four buttons. 124 00:09:36,760 --> 00:09:40,710 One button, labeled Set Single Alarm, that sets 125 00:09:40,710 --> 00:09:43,600 a single alarm to go off in two minutes. 126 00:09:44,670 --> 00:09:49,972 One button, labeled Set Repeating Alarm, that sets a repeating alarm 127 00:09:49,972 --> 00:09:51,718 that will go off in two minutes, 128 00:09:51,718 --> 00:09:56,031 and then continue to go off every 15 minutes after that. 129 00:09:56,880 --> 00:10:03,440 One button, labeled Set Inexact Repeating Alarm, that sets a repeating alarm 130 00:10:03,974 --> 00:10:08,332 that should go off every 15 minutes, starting in about two minutes. 131 00:10:09,030 --> 00:10:14,081 Now because this is an inexact alarm, Android will try to fire the alarm 132 00:10:14,081 --> 00:10:18,200 every 15 minutes but will exercise a lot of flexibility 133 00:10:18,204 --> 00:10:21,160 in when exactly those alarms go off. 134 00:10:22,350 --> 00:10:26,380 And finally, one button labelled Cancel Repeating Alarm, 135 00:10:26,920 --> 00:10:31,806 and that will cancel any currently active repeating or inexact repeating alarms. ///// 136 00:10:33,492 --> 00:10:36,590 Now, I'll click the button labeled Set Single Alarm, 137 00:10:38,370 --> 00:10:40,740 and as you can see, the toast message suggests 138 00:10:40,740 --> 00:10:44,750 that the application has now set a single alarm, 139 00:10:44,750 --> 00:10:47,620 and in this case, the alarm should go off in 140 00:10:47,620 --> 00:10:48,240 two minutes. 141 00:10:49,290 --> 00:10:51,270 And when it does, the code will 142 00:10:51,270 --> 00:10:55,160 place a user notification in the notification area. 143 00:10:56,390 --> 00:10:59,060 Let's come back at that point and see what happens. 144 00:11:01,030 --> 00:11:07,250 So, now we're back watching the device, and there's the notification 145 00:11:07,250 --> 00:11:13,720 asking if I'm playing Angry Birds again. Let me pull down on the notification area. 146 00:11:13,720 --> 00:11:16,230 The notification view tells me that this is 147 00:11:16,230 --> 00:11:18,720 a kind reminder to get back to studying. 148 00:11:20,460 --> 00:11:22,502 If I click on this notification view, 149 00:11:22,502 --> 00:11:26,240 the AlarmCreate application gets brought back up. 150 00:11:28,570 --> 00:11:30,940 Now before we move forward, let's take a 151 00:11:30,940 --> 00:11:33,770 look at the source code for this application. 152 00:11:37,060 --> 00:11:39,834 Now here I've opened the application in the 153 00:11:39,834 --> 00:11:42,440 IDE, and now I'll open the main activity. 154 00:11:44,400 --> 00:11:46,340 Let's take a look at the onCreate method. 155 00:11:47,690 --> 00:11:51,605 First, the code gets a reference to the AlarmManager service. 156 00:11:52,820 --> 00:11:56,030 Next, the code creates an intent whose 157 00:11:56,030 --> 00:11:59,360 target is the alarm notification receiver class. 158 00:12:00,580 --> 00:12:02,125 This intent is then wrapped in a 159 00:12:02,125 --> 00:12:06,790 PendingIntent that will cause this intent to be broadcast. 160 00:12:08,130 --> 00:12:12,710 And after that, the code creates a second intent, which this time is 161 00:12:12,710 --> 00:12:17,450 targeted to another class called AlarmLoggerReceiver. 162 00:12:17,450 --> 00:12:21,840 And as before, this intent is wrapped in a PendingIntent that 163 00:12:21,840 --> 00:12:25,450 will ultimately cause the intent to be broadcast to that receiver. 164 00:12:26,970 --> 00:12:27,070 Now, 165 00:12:27,070 --> 00:12:31,180 scrolling down, the code sets up the four buttons that we saw earlier. 166 00:12:32,950 --> 00:12:38,920 The first button, when pressed, will set up two one-shot alarms. 167 00:12:38,920 --> 00:12:43,700 The first alarm is scheduled to go off two minutes after the button is pressed. 168 00:12:44,710 --> 00:12:48,860 The second of this pair will go off about five seconds later. 169 00:12:50,700 --> 00:12:53,170 The second button, when pressed, 170 00:12:53,170 --> 00:12:56,220 will set up a pair of repeating alarms. 171 00:12:56,220 --> 00:13:01,030 The first alarm is scheduled to go off in two minutes, or two minutes 172 00:13:01,030 --> 00:13:05,460 after the button is pressed, and then go off every 15 minutes after that. 173 00:13:06,880 --> 00:13:11,760 The second alarm of the pair will go off about five seconds after the first. 174 00:13:13,610 --> 00:13:19,760 The third button, when pressed, will set up two inexact repeating alarms. 175 00:13:19,760 --> 00:13:23,180 The first alarm is scheduled to go off roughly every 176 00:13:23,180 --> 00:13:27,920 15 minutes, starting two minutes after the button is pressed. 177 00:13:27,920 --> 00:13:30,790 And again, the second alarm is scheduled to 178 00:13:30,790 --> 00:13:34,260 go off about five seconds after the first. 179 00:13:34,260 --> 00:13:40,170 Now remember, because this is an inexact repeating alarm, Android has 180 00:13:40,170 --> 00:13:45,070 considerable flexibility in the exact timing of both of those alarms. 181 00:13:45,070 --> 00:13:48,370 And in particular, Android will try to minimize the 182 00:13:48,370 --> 00:13:50,695 number of times it needs to wake up the 183 00:13:50,695 --> 00:13:54,745 device if it's sleeping, for instance, by grouping separate 184 00:13:54,745 --> 00:13:57,410 alarms to go off roughly at the same time. 185 00:13:59,420 --> 00:14:03,840 Finally, the fourth button, when pressed, will cancel existing alarms. 186 00:14:04,940 --> 00:14:09,260 In particular, this is important for repeating alarms, which will continue 187 00:14:09,260 --> 00:14:13,960 to go off until they're cancelled or until the device shuts down. 188 00:14:17,850 --> 00:14:22,032 Returning back to the running application, I'll now press 189 00:14:22,032 --> 00:14:25,558 the Set Repeating Alarm button, and this sets some 190 00:14:25,558 --> 00:14:28,674 new repeating alarms that will first go off in 191 00:14:28,674 --> 00:14:32,366 two minutes and then every 15 minutes after that. 192 00:14:32,366 --> 00:14:35,786 [BLANK_AUDIO] 193 00:14:35,786 --> 00:14:36,840 Let's come back when we're ready. 194 00:14:38,210 --> 00:14:39,870 Okay, so we're back now, and it's been 195 00:14:39,870 --> 00:14:42,660 about two minutes since the alarms were set. 196 00:14:43,970 --> 00:14:47,080 There's the notification showing that the alarm went off. 197 00:14:48,600 --> 00:14:51,621 The next alarm will come along in about 15 minutes. 198 00:14:51,621 --> 00:14:53,920 Let's take a break now, and when we come 199 00:14:53,920 --> 00:14:58,120 back, we'll examine the LogCat output for this application. 200 00:15:01,330 --> 00:15:03,542 So a bit more than 15 minutes has 201 00:15:03,542 --> 00:15:07,245 passed, and here's the application open in the IDE. 202 00:15:07,245 --> 00:15:14,070 I'll now expand the LogCat view, and I'll filter the LogCat 203 00:15:14,070 --> 00:15:19,546 output to just show log messages that have a tag coming from this application. 204 00:15:19,546 --> 00:15:26,380 I'll type tag:alarm, and that leaves just the 205 00:15:26,380 --> 00:15:28,350 messages that we're interested in now. 206 00:15:29,920 --> 00:15:34,610 As you can see, there are four messages, two from the first time the alarms 207 00:15:34,610 --> 00:15:40,140 fired, and two more from when the alarms went off again after 15 minutes. 208 00:15:41,330 --> 00:15:45,350 And notice that the two alarms which were scheduled to go off with five 209 00:15:45,350 --> 00:15:51,540 seconds between them, do in fact go off with that interval of time between them. 210 00:15:51,540 --> 00:15:53,920 So those were repeating alarms. 211 00:15:53,920 --> 00:15:57,060 Let's go back now to the application and take a look at 212 00:15:57,060 --> 00:15:59,155 what happens when we use the 213 00:15:59,155 --> 00:16:03,070 SetInexactRepeating method to set these same alarms. 214 00:16:05,120 --> 00:16:06,280 So here's my device again. 215 00:16:06,280 --> 00:16:10,610 And now I'll pull down on the notification area 216 00:16:10,610 --> 00:16:12,680 and use it to go back to the application. 217 00:16:14,100 --> 00:16:17,980 First, I'll cancel the existing alarms, and 218 00:16:17,980 --> 00:16:21,230 next I'll set the inexact repeating alarms. 219 00:16:22,910 --> 00:16:26,080 So let's let the application run for awhile, and then 220 00:16:26,080 --> 00:16:30,190 we'll take another look at the LogCat output for this application. 221 00:16:30,190 --> 00:16:32,620 So here we are back in the IDE, and 222 00:16:32,620 --> 00:16:35,380 about 20 minutes has passed since we last talked. 223 00:16:36,810 --> 00:16:39,080 Let's go back to the LogCat view. 224 00:16:39,080 --> 00:16:44,210 And here you can see that there are now four new messages, two from the first time 225 00:16:44,210 --> 00:16:49,280 the alarms fired and two more from the second time those alarms went off. 226 00:16:51,700 --> 00:16:58,140 And some things to notice are that even though at 11:19, we set the alarms to go 227 00:16:58,140 --> 00:17:01,600 off starting in two minutes, the first set of 228 00:17:01,600 --> 00:17:05,859 alarms actually went off after four or five minutes. 229 00:17:05,859 --> 00:17:08,280 And the second thing to notice, is that even 230 00:17:08,280 --> 00:17:10,359 though the pair of alarms were scheduled to go 231 00:17:10,359 --> 00:17:14,780 off with a five second delay between them, Android 232 00:17:14,780 --> 00:17:17,460 has actually fired them at essentially the same time. 233 00:17:17,460 --> 00:17:22,569 And again, because these are inexact repeating alarms, 234 00:17:22,569 --> 00:17:26,710 Android was free to modify the exact alarm timings. 235 00:17:31,390 --> 00:17:33,980 So that's all for our lesson on alarms. 236 00:17:33,980 --> 00:17:37,320 Please join me next time for a discussion of networking. 237 00:17:37,320 --> 00:17:39,052 See you then. 238 00:17:39,052 --> 00:17:43,760 [BLANK_AUDIO]