Reputation: 4033
It seems that the only way to time actions based on the actual elapsed time (as opposed to uptime, which stops when the device sleeps) is the AlarmManager.
Is there an an easy way to do "wallclock"-based delayed exectuion, for example through an open-source wrapper around AlarmManager?
For normal timing operations, you can use a handler, which is as easy as such a simple task should be:
removeCallbacksAndMessages(null)
However, Handler only supports uptime-based delays, which sometimes are not sufficient (e.g. if you want to check the server for new messages every 15 minutes).
If you want those, it seems that you have to use the AlarmManager, which is not very comfortable:
Upvotes: 0
Views: 567
Reputation: 1006744
For normal timing operations, you can use a handler
Only from a foreground activity. Any other use of Handler
for long-term polling is unreliable at best, even ignoring your concerns regarding uptime calculations.
Define an action for your alarm
This is not necessary. It is not even a good idea.
Create a receiver (either by creating a dedicated receiver class and declaring it the manifest, or implementing the interface, registering the receiver using registerReciever, and unregistering it when done)
If you want the event to occur when you are not in the foreground and the alarm to go off while the device is asleep (_WAKEUP
alarms), the manifest-registered receiver is required. If _WAKEUP
is not needed, a service will suffice. If you only need to be in the foreground and receive the event in an activity, use createPendingResult()
to give you a PendingIntent
that will trigger onActivityResult()
of your activity. Though, in this latter case, it would make more sense to use postDelayed()
on a View
or Handler
.
and store the pending intent if you want to cancel the alarm
If storing a PendingIntent
is an option, then Handler
is all you need, and AlarmManager
is unsuitable. To cancel an alarm, you need an equivalent PendingIntent
(one where the underlying Intent
objects match based on filterEquals()
and where the PendingIntent
operation [activity, service, broadcast] is the same).
When you want to cancel the alarm, cancel it using the stored pendingIntent
No, you cancel it by creating an equivalent PendingIntent
.
Should you decide to have multiple intents or intents with changing data, you will have to save them all to clean up the alarm manager afterwards
No, you cancel them by creating an equivalent PendingIntent
.
Is there an an easy way to do "wallclock"-based delayed exectuion, for example through an open-source wrapper around AlarmManager?
Creating wrapper code for this that covers 80% of the work would have taken you less time than it did to write your question. I am not aware of a dedicated library for this, partly because there wouldn't be all that much to it.
Or, use ScheduledExecutorService
and a WakeLock
, for short-term things. This is unsuitable for "every 15 minutes" scenarios, as it keeps the device awake all of the time.
Upvotes: 0