Android AlarmManager without turning screen on - android

My application have a realtime module that should ping the server every 60 seconds. Without this, the connection will be dropped and the device will need to reconnect again.
The first attempt was to use a Thread.Sleep to make the pinging thread runs at the desired frequency. The second attempt was to use the ScheduleExecutorService. Both worked very well, but only when the device was charging or with the screen turned on.
After reading a bit, I realized that this behavior happens because the device's processor sleeps and this interferes on the timers. So, the recommendation is to use the AlarmManager...
After start using it, I noticed the my device's screen started to be turned on frequently and I think that this is caused by the alarmmanager that 'wakes the device up'. I searched o bit to see how to use AlarmManager to execute some background actions even if the device is sleeping, without turning the screen on, but nothing was found.
So, there is anyway to use AlarmManager or other approach to accomplish this? Execute a background task even if the device is sleeping, without turning the screen on?
PS1: I know the battery consumption implications due this approach and the request about not turning the screen on is to minimize it's impact.
PS2: The AlarmManager's intent is being consumed by a background service.

Alarm Manager does not turn the screen on. From the docs,
When an alarm goes off, the Intent that had been registered for it is broadcast by the system, automatically starting the target application if it is not already running.
I am using it in my code and it does not turn the screen on unless I explicitly set a wake lock policy that turns it on. Take a look at WakeLock
The last 3 are deprecated as of API level 17.
I recommend you to use a PARTIAL_WAKE_LOCK for your task. or you can take a look at WakefulBroadcastReceiver

If you are using onReceive() method, that may be acquiring your wakelock. Remove the WakeLock parameter in onReceive().

Related

Does need Broadcast receiver to WakeLock

I have two questions.
I want fire a Broadcast receiver using AlarmManager and show a notification in onReceive method. Should I use from WakeLoke for this?
What is different between setAlarmClock() and setExactAndAllowWhileIdle() ?
I use (as you wrote) the onReceive method to start a newWakeLock and it works fine for me.
The difference lies in the behavior in doze mode (Doze Mode: https://developer.android.com/training/monitoring-device-state/doze-standby).
I do not know your exact problem, but I worked very hard to develop an app which contains few timers and every timer should make a notification at the exact time even the screen is locked and the device is in the doze mode. My solution is to fire an Broadcast over an AlarmManager with the setExact(...) method.
Answer your question in reverse order
.2. setExactWhileIdle guarantees that if the system is not sleeping and not in doze, the alarm will go off within 1 minute of the given time. if the system is in doze mode, the alarm will go off within 15 minutes of the given time. In practice, if the system is not in doze mode or low on battery, the alarm will go off on time. On the other hand, setAlarmClock is the closest one can get to a guarentee that the system will deliver the alarm at a specific time; this does come at a relatively large drain on battery. So, if your goal is to implement highly time sensitive notifications such as an alarm clock, then use setAlarmClock. Otherwise try to avoid it.
.1. according to the documentation, upon an alarm being dispatched from setExactAndAllowWhildIdle or setAlarmClock:
the app will also be added to the system's temporary power exemption list for approximately 10 seconds to allow that application to acquire further wake locks in which to complete its work.
My suggestion is that if all you are doing is posting a notification, then a wake lock is not necessary. Otherwise, if you are doing longer running work, use a wake lock
Obligatory Disclaimer: battery drain is a real thing. please don't make an app that drains the battery. do everything in your power to design your app not to disturb the systems power optimization. All exact alarms and especially setAlarmClock disrupt the systems attempts to optimize battery. If its necessary, then its necessary. Otherwise, do not do it.

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.

Acquire wake lock, release it and acquire it again while the phone is sleeping

I think this is pretty much the standard case already described in other SO question but I still need a clarification on this matter:
So I have an Android app with an Actvity and a Service. The Activity is not of interest but the Service. The Service has to send some message to a remote server every minute. From what I understand, I need to use WakeLocks to keep the CPU running while allowing the screen to go off (so that I can fix the problem where the service stops when the screen is powered off). So far so good.
My question is: can I acquire the lock, send the message to the server, release the lock AND acquire it again after one minute so that during this one minute pause the CPU is sleeping, too. With the ultimate goal to save the battery. I fear the answer is "no" because once you let the CPU to sleep, you cannot wake it up unless from a lower level (OS and not app).
Best regards
The response is simple: no. What you can do in this case is set a PendingIntent and use the Android Alarm manager to be woken up every minute.
The alarm manager is the way to go - but you also need to delegate from the alarm receiver to a WakefulIntentService to do the work (as the receiver will ANR after 5 seconds). See PowerManager.PARTIAL_WAKE_LOCK android for links.

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?

Android 2.2: Turning of screen under certain times of the day by code

I would like to know if there is any way to turn off the screen on an android device on for example 19.00-22.00 every day. I have some tablets running in kiosk mode, and i want the screens to turn off when no one is using them and the store is closed.
Thanks
Screens will turn off automatically, if you have that set up properly in the device settings.
You can use AlarmManager and a WakeLock to arrange to keep the device screen awake during business hours. Have the AlarmManager start up a service that acquires the WakeLock and waits until closing time. You will need to use startForeground() in the service to prevent Android from killing off your service.
In the real world, this implementation would suck, as it forces you to keep a service running all the time -- if you let the service shut down, you lose the WakeLock and can never release() it, so the screen will never shut off. So, outside of this sort of kiosk thing, I do not recommend this technique.

Categories

Resources