AlarmManager's wake lock when starting a service
Asked Answered
C

1

8

Android's AlarmManager Javadoc states

When an alarm goes off, the Intent that had been registered for it is broadcast by the system,

There is an AlarmService (package com.example.android.apis.app) in the API demos supplied with Android which demonstrate AlarmService in use.

In it we have the following (edited for clarity):

PendingIntent mAlarmSender = PendingIntent.getService(AlarmService.this,
            0, new Intent(AlarmService.this, AlarmService_Service.class), 0);
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime, 30*1000, mAlarmSender);

So in this example it doesn't do a PendingIntent mAlarmSender = PendingIntent.getBroadcast(...); instead it does a getService which the Javadoc never alludes to.

The reason I am asking about this is because of the implications of the CPU wake lock. The Javadoc says that the AlarmManger's wake lock will be released once a Broadcast receiver's onReceive() returns.

What I am wondering is what are the wake lock implications if you use an Alarm like in the example? The Javadoc doesn't seem to address this. If anything it seems to imply that you must use the broadcast technique when setting alarms.

Coltoncoltsfoot answered 16/11, 2011 at 11:58 Comment(0)
P
6

What I am wondering is what are the wake lock implications if you use an Alarm like in the example?

There are no guarantees that your service will get control before the device falls asleep.

If anything it seems to imply that you must use the broadcast technique when setting alarms.

For _WAKEUP alarms, yes, as that is the only path in which we are guaranteed to get control while the device is still awake.

Since the work to be done by the _WAKEUP alarm is typically beyond the scope of what you can safely do in onReceive() of a manifest-registered BroadcastReceiver, a common pattern is to delegate the work to an IntentService. To that end, I have packaged up WakefulIntentService, to implement the pattern for safely passing control to an IntentService and keeping the device awake long enough for the service to do its work.

Pietje answered 16/11, 2011 at 12:36 Comment(5)
also.. what is the best way to cancel a WakefulIntentService?Coltoncoltsfoot
@Tim: I'm not sure what you mean by "cancel a WakefulIntentService". You can cancel the alarm via cancel() on AlarmManager.Pietje
actually after looking at this again. To cancel() you need the same PendingIntent that started it which I don't have access to. From the demo AppListener class... I could set a flag which is checked in the scheduleAlarms(..) method which would then immediately use the pi variable to cancel the same alarm? Is this a reasonable solution. I'd prefer to leave your WakefulIntentService class as is - using it as a libraryColtoncoltsfoot
Small ommission..I was going through your README.markdown instructions and noticed you'd forgotten to include the fact that you need the RECEIVE_BOOT_COMPLETED permission also.Coltoncoltsfoot
@Tim: "To cancel() you need the same PendingIntent that started it which I don't have access to." -- no, you need an equivalent PendingIntent, meaning a PendingIntent created using an equivalent Intent, where "equivalent" means "same component, action, Uri, categories, and MIME type". Re: small omission, yes, I forgot to mention that requirement if you're using the new AlarmReceiver. It also pointed out some places where the markdown wasn't being converted properly in that README. Thanks!Pietje

© 2022 - 2024 — McMap. All rights reserved.