The following is the first few sections of a chapter from The Busy Coder's Guide to Android Development, plus headings for the remaining major sections, to give you an idea about the content of the chapter.
Many applications have the need to get control every so often to do a bit of work. And, many times, those applications need to get control in the background, regardless of what the user may be doing (or not doing) at the time.
The solution, in some cases, is to use
AlarmManager, which is roughly
cron on Linux and macOS and Scheduled Tasks in Windows. You
AlarmManager when you want to get control back, and
will give you control at that time.
Android 5.0 added a separate
is designed for background work.
JobScheduler is more sophisticated than
AlarmManager. For example, if you need an Internet
connection to do your work,
JobScheduler will only give you control
if there is an Internet connection. If your app’s
minSdkVersion is 21 or higher, you
might consider using
JobScheduler instead of
is covered in an upcoming chapter.
The two main axes to consider with scheduled work are frequency and foreground (vs. background).
If you have an activity that needs to get control every second, the
simplest approach is to use a
postDelayed() loop, scheduling a
to be invoked after a certain delay, where the
Runnable reschedules itself
to be invoked after the delay in addition to doing some work. We saw this
in the chapter on threads.
This has the advantages of giving you control back on the main application
thread and avoiding the need for any background threads.
On the far other end of the spectrum, you may need to get control on a somewhat
slower frequency (e.g., every 15 minutes), and do so in the background,
even if nothing of your app is presently running. You might need to poll
some Web server for new information, such as downloading updates to an RSS
feed. This is the scenario that
AlarmManager excels at. While
works inside your process (and therefore does not work if you no longer
have a process),
AlarmManager maintains its schedule outside of your
process. Hence, it can arrange to give you control, even if it has to
start up a new process for you along the way.
There are a variety of things you will be able to configure about your
scheduled alarms with
The biggest one is whether or not the scheduled event should wake up the device.
A device goes into a sleep mode shortly after the screen goes dark. During this time, nothing at the application layer will run, until something wakes up the device. Waking up the device does not necessarily turn on the screen — it may just be that the CPU starts running your process again.
If you choose a “wakeup”-style alarm, Android will wake up the device to give you control. This would be appropriate if you need this work to occur even if the user is not actively using the device, such as your app checking for critical email messages in the middle of the night. However, it does drain the battery some.
Alternatively, you can choose an alarm that will not wake up the device. If your desired time arrives and the device is asleep, you will not get control until something else wakes up the device.
You can create a “one-shot” alarm, to get control once at a particular time in the future. Or, you can create an alarm that will give you control periodically, at a fixed period of your choice (e.g., every 15 minutes).
If you need to get control at multiple times, but the schedule is irregular, use a “one-shot” alarm for the nearest time, where you do your work and schedule a “one-shot” alarm for the next-nearest time. This would be appropriate for scenarios like a calendar application, where you need to let the user know about upcoming appointments, but the times for those appointments may not have any fixed schedule.
However, for most polling operations (e.g., checking for new messages every NN minutes), a repeating alarm will typically be the better answer.
If you do choose a repeating alarm, you will have your choice over having (relatively) precise control over the timing of event or not.
If you choose an “inexact” alarm, while you will provide Android with a suggested time for the first event and a period for subsequent events, Android reserves the right to shift your schedule somewhat, so it can process your events and others around the same time. This is particularly important for “wakeup”-style alarms, as it is more power-efficient to wake up the device fewer times, so Android will try to combine multiple apps’ events to be around the same time to minimize the frequency of waking up the device.
However, inexact alarms are annoying to test and debug, simply because you do not have control over when they will be invoked. Hence, during development, you might start with an exact alarm, then switch to inexact alarms once most of your business logic is debugged.
Note that Android 4.4 changes the behavior of
AlarmManager, such that
it is more difficult to actually create an exact-repeating alarm schedule.
This will be examined in greater detail shortly, as we review the various
methods and flags for scheduling
As part of the alarm configuration, you will tell Android when the event is to occur (for one-shot alarms) or when the event is to first occur (for repeating alarms). You can provide that time in one of two ways:
For most polling operations, particularly for periods more frequent than once
per day, specifying the time relative to now is easiest. However, some alarms
may need to tie into “real world time”, such as alarm clocks and calendar
alerts — for those, you will need to use the real-time clock (typically
by means of a Java
Calendar object) to indicate when the event should
And, of course, you will need to tell Android what to do when each of these
timer events occurs. You will do that in the form of supplying a
PendingIntent. First mentioned in the chapter on services,
PendingIntent is a
Parcelable object, one that indicates an operation
to be performed upon an
While the service chapter discussed an Android activity using
createPendingResult() to craft such a
PendingIntent, that is usually
not very useful for
AlarmManager, as the
PendingIntent will only be
valid so long as the activity is in the foreground. Instead, there are
static factory methods on
PendingIntent that you will use instead
getBroadcast() to create a
PendingIntent that calls
on a supplied
Intent). That being said, our next sample will use
createPendingResult(), to keep the sample as simple as possible.
The preview of this section apparently resembled a Pokémon.
The preview of this section left for Hollywood to appear in a reality TV show.
The preview of this section is sleeping in.
The preview of this section was accidentally identified as an Android 'tasty treat' by the Cookie Monster.
The preview of this section was stepped on by Godzilla.
The preview of this section apparently resembled a Pokémon.
The preview of this section may contain nuts.
The preview of this section is out seeking fame and fortune as the Dread Pirate Roberts.
The preview of this section is presently indisposed.