Screen ON/OFF receivers on a service and battery life - android

I'm new to Android and Java programming, so I would like to clear up couple of questions I have.
I've written a background service that verifies something every 10 seconds, and, based on some conditions, it may execute something (or may not). This is implemented using a Timer.
My understanding until now is that the timer in the service will run even when the screen is off, so every 10 seconds, even with the screen off, the timer will fire up.
I suppose that this will have an impact on battery life, though I don't know how much or how to measure this.
Now, I don't need the service to do anything while the screen is off, so I'm thinking about registering the Screen OFF and Screen ON broadcast Intents.
On Screen OFF, the code would stop the timer – or would it be better to stop the whole service? – and on Screen ON it would start the timer (or service).
My thought on this direction is that my application will consume less of the battery than it would otherwise
Please tell me if my logic makes sense
If I'm wrong or if there are better ways to achieve this, please let me know.
Thank you!

Related

Scheduling Repeating Events -- Handler.PostDelayed and Doze

Context
I'm working on a screen filter app (like f.lux) for Android. I'm currently working the feature to gradually fade in the filter as the sun sets. The state does not matter when the screen is off, but when the screen is on, it's important that the fade progress be correct (or immediately updated).
Technical requirements
I want to fire a series of intents at semi-regular intervals.
When the screen is off, they can be ignored / discarded, except:
when the screen turns on, the most recent intent must be fired immediately.
I do not want to drain the battery unnecessarily.
Obvious solutions and why they don't work
I could use AlarmManager.setInexactRepeating, which is supposedly the most energy-efficient of the alarms, except:
Your alarm's first trigger will not be before the requested time, but it might not occur for almost a full interval after that time.
I think this implies that the first trigger will necessarily happen within the first interval, meaning the device will be woken, causing unnecessary battery drain.
I could use AlarmManager.set to schedule the first alarm. When it goes off, I could update the screen, then schedule the next alarm. This would work, but would wake up older devices (without Doze) on each alarm, instead of waiting until the screen turns on. It's also using AlarmManger as a timer, which the documentation explicitly recommends against:
For timing operations (ticks, timeouts, etc) it is easier and much more efficient to use Handler.
Okay, so,
I could set a single alarm to starts up a Handler, which would update the UI periodically. But wait: this relies on postDelayed, which says (emphasis mine):
Time spent in deep sleep will add an additional delay to execution.
I think that means, when the device wakes up from sleep, the next update might not happens for a whole interval. Am I reading this right? Forcing the user to wait a minute or two before the next update is a deal-breaker.
CountDownTimer and ValueAnimator both use this method in their implementations, so if my interpretation of Handler is right, they're both out.
I could use a handler-based method and also receive events when the screen is turned off, at which point I'd cancel the existing animation, then start a new one. This looks to be the best solution, but it seems like there should be a simpler way to do it.
Conclusion
There are a ton of other SO questions on this topic. Everyone and their mother recommends using a Handler, but there's absolutely no information about how it behaves when the device goes to sleep, aside from the quote above. It's really weird that (apparently) nobody else has run into this issue -- am I doing something really unusual, or missing something basic?
Can anybody provide insight about how Handler.postDelayed really behaves when the device goes to sleep, and recommend what I should do in this particular instance?

How to update clock widget if screen is turned off?

I used this tutorial http://forum.xda-developers.com/showthread.php?t=1732939 to create a simple clock widget.
Sadly it's not running very well. When the screen is turned off, the widget won't update anymore so it won't show the corret time.
So, how can I update the widget even if the screen if turned off?
Take a look at Repeating Alarms:
They operate outside of your application, so you can use them to trigger events or actions even when your app is not running, and even if the device itself is asleep.
https://developer.android.com/training/scheduling/alarms.html
Or at "WakeLock":
One legitimate case for using a wake lock might be a background service that needs to grab a wake lock to keep the CPU running to do work while the screen is off. Again, though, this practice should be minimized because of its impact on battery life.
https://developer.android.com/training/scheduling/wakelock.html#cpu
Using the first approach can help you to get your point.

Monitor every battery state change even with screen off

I want my app to monitor every percent change and be able to execute some code when it changes even when the screen is off.
Yes, I know this is a bad idea and will drain battery unnecessarily. I am giving the user the option to turn this off. Also, this is more of an experiment at this point than a user-friendly feature. So please do not answer that I should not monitor every change.
I also know this is possible because Tasker implements this quite well. You can set a profile to do something on "Battery Changed" and it works when the screen is off. How is Tasker doing this?
From my research I have found that I will probably need to use AlarmManager and a partial wake lock from the PowerManager class. However I don't know how to best use these classes. Should I set an alarm manager to check every minute for a change? Tasker seems to not eat up too much battery when doing this so I would like to keep that in mind.
I have this working when the screen is on just fine. I have a service that registers an ACTION_BATTERY_CHANGED intent filter and a receiver to implement my code that I want to run. However when the screen is off, the code does not run until I "wake" the device by turning on the screen.
How is Tasker doing this?
You would have to ask the developers of Tasker.
Should I set an alarm manager to check every minute for a change?
It would not need to be nearly that frequent. You can only get battery charge levels in integer percentages, at best. Checking every 5-10 minutes is probably more than sufficient. You could also consider:
Letting users control the polling frequency
Implementing a learning algorithm that tries to determine a good polling interval based upon how the device has behaved previously
I have a service that registers an ACTION_BATTERY_CHANGED intent filter and a receiver to implement my code that I want to run.
Yuck. There is no added value for you tying up memory waiting for the battery level to tick over.
You can get the current battery level by calling registerReceiver() with an IntentFilter for ACTION_BATTERY_CHANGED and a null BroadcastReceiver. registerReceiver() will return the last ACTION_BATTERY_CHANGED broadcast that went out. Hence, again, a polling mechanism should be just fine.

Android Timer/Handler/Thread.sleep() with screen off don't work correctly

I'm developing an application which needs to run small chunks of code frequently (once every two seconds, for example). I've tried to make it work using the simple Thread.sleep() (or android.os.SystemClock.sleep() to avoid interrupts, and finally I've tried with Timer and Handler), but the result is that the time that the program sleeps is random (or it simply doesn't run if I use Timer or Handler as the system discards they messages when the screen is off), as the system goes to a deep sleep mode during screen off.
For example the code works right if I have the phone plugged into the charger, or is playing music (that avoids the deep sleep mode), but when the phone isn't doing anything the time can grow from two seconds sleep up to minutes of sleep.
From https://groups.google.com/forum/#!topic/android-developers/Eqwp8Uiy2f0 seems that the only alternative is to use the AlarmManager to force the wake, but that way will probably cause too much battery drain.
Is there any alternative?
If not, is there any way to detect when the system goes into the deep sleep mode?
It is too late but may be useful for somebody else.
Yes, Timers does not work in deep sleep mode.I think there is no other better way than AlarmManager to run something periodically in deep sleep mode.
Also, as your frequency is just 2 seconds I think you may have to go for exact alamrs (setExact() ) as the regular alarm may not serve you better if your requirement is critical in time. And sometimes even setExact might not capture the wake lock I observed. So you have to acquire your own (PARTIAL_..) wake lock and, do stuff and release the lock.
But is it must that you have to run evvery 2 seconds ?
If not continue using Timers which will continue working automatically after the device wake up.
Take a look at Should I use AlarmManager or Handler?

Run a service in the background forever..? Android

I am doing a Battery Consuming research on the Android phone. I want to run a Battery Check every 10 min till the battery totally dies. I have been having problems to make it work.
At my first try, I use a timer in a service class, and schedule the battery check every 10 mins. But soon I found that the service got paused when the screen goes off.
Then I try to use AlarmService, I use a alarm call to wake my service every 10 mins and to check the battery level and save the data to a file on the sdcard. It works with the screen off. However, I only got data of 9 hours...it seems that the AlarmService stop at some point after several hours. I don't know why it is like this, has the system killed it for memory issues?
So my question is, has anyone written some service to run (like forever) in the background before? How do you do it and I'd appreciate very much for a sample code?
I am currently reading some posts saying that there's a partial wake lock I can use to keep the service alive.. is this the correct way to do it?
Thanks a lot and I hope I can get some useful answers here.
At my first try, I use a timer in a
service class, and schedule the
battery check every 10 mins. But soon
I found that the service got paused
when the screen goes off.
You probably did not hold a WakeLock, so the device fell asleep.
it seems that the AlarmService stop at
some point after several hours
I rather doubt it.
So my question is, has anyone written
some service to run (like forever) in
the background before?
It is not possible to create a service that will run forever. It should be possible to create a scheduled task via AlarmManager that will be invoked "forever".
I am currently reading some posts
saying that there's a partial wake
lock I can use to keep the service
alive.. is this the correct way to do
it?
I'm not sure what "it" is. But, if you want to keep the device awake -- whether for your first approach or just while you are doing work triggered by an AlarmManager -- you need to hold a WakeLock.
Here is a project that does almost exactly what you describe for the AlarmManager, minus checking the battery level, but using a WakefulIntentService to ensure the device stays awake. If you cannot get this code to run until the battery shuts down, join the cw-android Google Group and report your findings, and I'll take a look at it.
http://github.com/commonsguy/cw-advandroid/tree/master/SystemServices/Alarm/

Categories

Resources