Whether you need to keep wake-lock or not should not be related to the amount of work your Service
does - theoretically, device can go to sleep even if the amount of work is small.
Wake-locks should be considered only if you absolutely must ensure that device can't sleep while the Service
is running. Cases like this are very rare. Some examples:
- Alarm clock applications (need to wake you up even if the device is sleeping)
- Real time messaging applications (need to notify you about new messages even if the device is sleeping)
Most applications don't have such a strict timing requirements. For example, the following are NOT good reasons to use wake locks:
- Periodic synchronization of data with the server (should be delayed until device awakes)
- Displaying current user's location on map (can be obtained when device awakens; but wake-lock will be needed for applications that monitor user's entire route)
If you really need to ensure that the device doesn't sleep during Service
execution, then you need to acquire a wake-lock (one of the several types). Let's assume that this is the case here.
You want to be able to start the "wakeful" Service
from application's UI (Activity
), and using AlarmManager
.
Starting from UI
Since the device should be completely awake in order for the user to interact with UI, you can safely assume that if you start the Service
in response to UI interaction it will have a chance to acquire a wake-lock (but do it as soon as the Service
is started).
Your solution covers this case.
Starting from AlarmManager
Unfortunately, there is no guarantee (at least no documented guarantee) that when AlarmManager
starts the Service
it will hold a wake lock and allow the Service
to acquire its own wake-lock. This means that the device can go to sleep after alarm fired, but before your Service
had a chance to acquire the wake-lock.
This means that your solution will "break" in this case.
The only documented scheme in which AlarmManager
will help you with wake-locks involves broadcasts:
The Alarm Manager holds a CPU wake lock as long as the alarm
receiver's onReceive() method is executing. This guarantees that the
phone will not sleep until you have finished handling the broadcast.
Once onReceive() returns, the Alarm Manager releases this wake lock.
This means that the phone will in some cases sleep as soon as your
onReceive() method completes. If your alarm receiver called
Context.startService(), it is possible that the phone will sleep
before the requested service is launched. To prevent this, your
BroadcastReceiver and Service will need to implement a separate wake
lock policy to ensure that the phone continues running until the
service becomes available.
This is where WakefulBroadcastReceiver comes in very handy.
Note that if you use this scheme, then there is no need to support a different one for "UI initiated" case - use the same approach in both cases.
You might also want to take a look at this library developed by @CommonsWare (I didn't use it myself though).