I need to get notified in code every X amount of time, even when the phone is sleeping.
So, My setup is a Service that sets a repeating alarm, and when it goes off it tells a BroadcastReceiver about it. From that receiver, I'm trying to start the same Service so that I can handle some code.
I don't have any problem running it when the phone is awake or is debug mode.
However, when I'm not debugging and the phone is sleeping, it looks like the Service is not running so non of my Alarms is handled.
Where am I doing wrong?
I only want my app's service to handle alarms periodically, even when the phone is sleeping (I moved to Alarms after having the same issues with a Timer object within the Service).
You need to acquire a wake lock.
www.vogella.com/blog/2011/02/07/android-wakelock/
Related
I am working with Android API especially Alarms, IntentService and notifications. I am using AlarmManager to schedule a periodic IntentService which might or might not fire notifications.
My questions is What happens when the device is in sleep mode?
Alarm will not fire and thus IntentService will not run at all. I am not sure if this will be the case.Will it make a difference if I make it a WakefulIntentService? I believe wake locks are needed to ensure the service keeps running after the BroadCastReciever returns. However, in this case there is no broadcast reciever.
Alarm and IntentService will run, but any notification will not have any impact since the device is sleeping. In this case, do I have to explicitly get a wakelock from PowerManager to fire notification ?
What happens when the device is in sleep mode?
That depends upon your type of alarm and the component your PendingIntent is to invoke.
If your alarm type ends in _WAKEUP, and you are using a broadcast PendingIntent, the device will wake up and remain awake through the call to onReceive() of the BroadcastReceiver. Once onReceive() returns, the device can fall asleep again. This is why WakefulIntentService and WakefulBroadcastRecevier were created -- to offer tested patterns for how to pass control to an IntentService and keep the device awake while the service completes its work.
If your alarm type ends in _WAKEUP and you are not using a broadcast PendingIntent, as the saying goes, your mileage may vary. You may not get control before the device falls back asleep. This is not a recommended pattern.
If your alarm types does not end in _WAKEUP, the device will not wake up due to your alarm.
With respect to the Notification, given the nature of the API, one hopes that it is the OS' responsibility to keep the device awake long enough for the ringtone or vibration pattern to play, as we do not know the precise instant when the Notification appears, nor do we know whether the ringtone will play (e.g., device is on silent mode).
I am developing an application that uses a Service as Contdown. When the user starts the countdown from the activity and the activity goes in background after the sleep button is pressed, I am using this Service to continue the countdown. When the count is finished the Service shows a notification with ringtone.
I use wait() "to count" the time in the Service. The strange behavior occurs when I use the application on a real device, but in debug mode. When Eclipse debugger is attached, the Service works well; when I test the application on the device without Eclipse debugger attached, the Service doesn't show the notification when the countdown is finished, unless the sleep button is repressed and the monitor is activated - then the notification and the ringtone are activated.
Can anyone can explain what causes this strange behavior? Maybe the issue is is related to Wake lock or a similar construct?
I use wait() "to count" the time in Service.
That is poor programming practice. Time elapses even without your tying up RAM to do it.
Anyone can explaine why this strange behavior?
The device fell asleep. This is normal, and desirable, behavior, to conserve battery life. With the USB cable plugged in, the device does not need to fall asleep, and if you checked the appropriate option in Developer Options, the device specifically will not fall asleep while plugged in.
Maybe is connected with Wake lock
Please do not use a WakeLock to keep the device awake for you to watch the clock tick by. Please use AlarmManager to get control when the countdown period is over. You can use a _WAKEUP-style alarm to arrange to wake up the device, and your BroadcastReceiver that gets control at that point can "launch a notification and ringtone". As a bonus, you can get rid of your service, so that your app can be better behaved on the user's device.
wait() calls are not guaranteed to wait for the right amount of time if the device goes to sleep. You should use AlarmManager to trigger your countdown timer instead.
I set an alarm with the flag RTC_WAKEUP to run a IntentService every 30 seconds to transmit location updates to a server. I'm planning to change the flag to RTC so it won't wake up the phone and just run when another process wake ups the phone. If I leave a LocationListener registered, will it still listen for location updates while the phone is asleep?
Yes - working location service has it's own wake lock. However better approach is manually set proper wake lock in your broadcast receiver. Please consider some optimization - sending data over network every 30s will drain battery.
You have multiple problems here.
I set an alarm with the flag RTC_WAKEUP to run a IntentService every 30 seconds to transmit location updates to a server.
First, you may not even get your first fix within 30 seconds, particularly if you are using GPS. You need to take into account that you may never get a fix (e.g., the user is in an underground location).
Second, please allow this figure to be user-configurable, including an option for "I'll upload the data manually please". As #piotrpo indicates, this is a significant drain on the battery. In fact, if you're using GPS, I doubt the battery will last more than a couple of hours.
Third, an IntentService will not work well in this case, because the IntentService will shut down before your fix arrives. At best, you'll leak memory. At worst, you won't get your fix, because Android terminates your process.
A better solution for doing background location checks is to use a regular Service, not an IntentService. The regular Service would register the LocationListener in onStartCommand(), plus arrange for a timeout notification (e.g., AlarmManager and set()) in case a fix is not available. When the fix arrives, run an AsyncTask to do your upload. When the AsyncTask completes, or if the timeout arrives and you did not get a fix, unregister the listener and call stopSelf() to shut down the service. Along the way, you will need to maintain your own WakeLock, to keep the device awake while all of this is going on.
For an example of most of this (minus the server upload part), see my LocationPoller.
If you are dead-set on this occurring every 30 seconds or so, you may as well not bother with AlarmManager at all. You would have to have an everlasting service, running all the time, with a permanent WakeLock and a permanent LocationListener. When fixes arrive in onLocationChanged(), upload them if they are more than 30 seconds from the previous one. And, be sure to wear a flame-retardant suit when you release the app, as those who run it may not like the results much.
I've been seeing some strange issues using the Alarm manager in Android, despite the fact that I'm using RTC (non Wakeup) the phone will reliably send the PendingIntents on the correct repeating intervals.
Details of my test
Device is not charging, just sitting on my nightstand while I slept
My service woke up on its repeat interval (30 minutes, an extreme I know) EVERY TIME
The service logged its activity in a file so I could read it in the morning
Now from my understanding the phone should be sleeping unless I wake it up and my Alarms should not be sent until the phone is awake.
Why was my service executing?
If another service is misbehaving and using the _WAKEUP variants of the alarm will my service wake up too?
Can I avoid being woken by another service, and just awake from the user turning the screen on?
Why was my service executing?
Presumably something else was having the device awake at those moments.
If another service is misbehaving and using the _WAKEUP variants of the alarm will my service wake up too?
Yes, though "misbehaving" is in the eye of the beholder.
Can I avoid being woken by another service, and just awake from the user turning the screen on?
Not directly via AlarmManager. You can watch for ACTION_SCREEN_OFF and ACTION_USER_PRESENT broadcasts, and perhaps disable your alarms between those.
I've just spent an hour trying to find out why my RTC alarm sends PendingIntents even when my phone is sleeping. And the answers is very simple, because it was pluged with USB so the phone had status "charging".
Presumably something else was having the device awake at those
moments.
A lot of applications with notification ads (like AirPush, Leadbolt ect) wake up the device.
I am new to the notion of WakeLock and need your help.
Questions:
I assume WakeLock to be some type of lock which when held by the executing code prevents the device from sleeping. What if the device is already in sleep/standby mode, will the code execute then? Assuming that it would never acquire a WakeLock?
When a long running task(abt 7-8 sec) is done in a background thread(AsyncTask) should I be bothered about holding a WakeLock? Does AsyncTask already acquire it for me?
links to official documentations and writeup on wakelocks are appreciated.
Thanks.
1.If the phone is in full sleep mode, aside from an incoming phone call, you could use an AlarmManager intent to wake the phone up.
From the AlarmManager class documentation:
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.
2.If you're working with an AsyncTask, you will want to publish results on to the UI thread on onPostExecute()
From the AsyncTask documentation:
AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
3.I suggest you have a read at the official documentation of Power Manager which gives a good introduction to the WakeLock concept.
Typically the only code that would run while the phone is sleeping is a BroadcastReceiver. Actually, the phone wakes up for a second, runs the BroadcastReceiver's code and sleeps again. Since you should never run long code in a BroadcastReceiver (use it to launch a Service instead), you can basically assume that your code is never run while the phone is sleeping. Of course, if you are using a BroadcastReceiver to start a Service, you should usually obtain a WakeLock.
With an AsyncTask initiated by the user, you don't really need to worry about WakeLocks. It is unlikely the phone will sleep while it is running. I'm not sure if they get a WakeLock, but putting my phone to sleep while running a standard AsyncTask doesn't seem to interrupt the it.
As SteD said, check this out: http://developer.android.com/reference/android/os/PowerManager.html
Basically the only time you need to worry about WakeLocks is when you either expect your task to be interrupted by sleeping (as is the case if you set an alarm that wakes the phone up briefly) or if you absolutley cannot have the task interrupted. Otherwise, just make sure that you gracefully handle any interruptions.