AlarmManager and Sleepy Android Apps

In my first article explaining How to Code an Android Widget, we covered the steps required to create a basic widget that updates on a non-frequent basis and uses standard components. We couldn’t get it to update the widget on a frequent basis however.

In this article, I will show you how to add a periodically firing update to your Widget using an ‘AlarmManager’. I make the assumption that you have already read the introduction Android Widget Coding article, or that you know the basics of App Widget programming.

Frequently Updating Widgets

Android widgets update their contents on a timed basis, waking the phone up to do so, even if the screen is off. If the update frequency is set too high, this can lead to excess battery usage. As a result, the Android system limits the frequency of widget updates to once every half hour or greater.

That’s no good if you want a frequently updating widget, like a clock. What we need here is a method of updating the widget frequently while the screen is on and only when the screen is on. Luckily there is a way this can be done, using a ‘AlarmManager‘, which is a system service wherein your code registers events to go off at particular times, or at particular periods. This allows something to happen at a particular time, even if the application is not running at that time. Even better, when you specify the right type of timer, you can tell it not to deliver the event if the phone is asleep at the time it goes off. This makes it perfect for our cause.

As with Widget updates, alarms are delivered as Intents, just as everything is in Android. So, the first thing we have to do is configure our application to listen to a custom intent type that we will create specifically for our clock updates.

Open up AndroidManifest.xml and add a new intent-filter beneath the existing filter for APPWIDGET_UPDATE. Because we are using a custom intent, we get to name it ourselves, but it should be fully qualified (i.e. have a reversed domain name on the front) so that we can differentiate between our intents and everyone else’s on the system. In this circumstance, I have chosen com.eightbitcloud.example.widget.8BITCLOCK_WIDGET_UPDATE as the name.

Next we need to write some code in our ‘ProviderHandler’ to configure the ‘AlarmManager’ to send out our intent on a regular basis. Load up the ‘WidgetProvider’ that we created in the first tutorial, and add the following methods:

onEnabled() and onDisabled() are called respectively when the first widget is created of your type, and the last is deleted. We want to start sending out the regular ticks when the first widget is created, and we want to stop the ‘AlarmManager’ when the last widget is deleted. We simply call AlarmManager.setRepeating() to create the repeating alarm, and then call cancel() when we are done with it.

Note that when we create the alarm, we specify an Alarm Type of AlarmManager.RTC. This type of alarm is only generated while the phone is awake. This is the feature that we rely upon to deliver updates only when the is awake, and not when the device is asleep.

Now we’ve told Android that our application is interested in receiving these intents, and we’ve configured the ‘AlarmManager’ to send the intents out on a regular basis. All that is left is to write the code that will handle the intents when they arrive. Alter your ‘WidgetProvider‘ class to include the following code:

This code listens for the intent, and updates the component contents when received. The actual code to update the widget is the same as it was in the previous article, but has been refactored into a method called updateAppWidget to avoid repeating ourselves. Have a look at the full code for the class for more information.

So there you have it. Using the ‘AlarmManager’ we can get the Android operating system to send our application an intent on a regular basis. In this example, we’ve used the technique to update a widget on a very frequent basis, but it can also be used to do periodic updates for other components in your application. As an example, I often see that people have background services running to update their network feeds on a periodic basis. This works, but the service sits there running all the time, taking up memory on the device. If they were to use an ‘AlarmManager’, they could simply wake up their service each time it needed to do an update.

I hope that this article has shown how easy the ‘AlarmManager’ is to use. As always, the code is available on GitHub at Widget Example. In a future article, we’ll look at how to introduce complex user interface components to widgets.

Bruce Cooper is an IT consultant who feels that in order to be able to serve his customers well he should have an understanding of the different technologies that are out there, and how they work. The best way to learn is through doing, so he often takes on small side projects to pick up a new technology.