Allowing the phone to sleep while using RTC alarm on Android - android

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.

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.

Sleep/idle mode leads to Wi-Fi lost

When I have internet connection, if I leave my Android wear device idle for around 20 to 30 minutes, internet connection stops.
In my app, I have connected with third party server, so sleep/idle mode leads to lose the connection with the server.
How can I handle this situation?
My requirement: my app should be always connected with the server to receive notifications.
If you want real time notifications, you'll need a Partial Wakelock to keep the service running, plus a WiFiLock to prevent the wifi network from going down. If you don't need realtime notifications, you can use AlarmManager or BroadcastReceiver or WakefulBroadcastReceiver or JobScheduler to schedule checks for new notifications, say every hour or so.
Note that if you use BroadcastReceiver, it is not guaranteed that CPU will stay awake when the broadcast is received inside onReceive(). However, if you use WakefulBroadcastReceiver,the CPU is guaranteed to stay awake until completeWakefulIntent is fired. WakefulBroadcastReceiver has been deprecated in Android O, in favour of JobScheduler
You can also read here about scheduling repeating events.
For devices with Doze mode:
The system exits Doze for a brief time to let apps complete their
deferred activities. During this maintenance window, the system runs
all pending syncs, jobs, and alarms, and lets apps access the network
If you need to set alarms that fire while in Doze, use
setAndAllowWhileIdle() or setExactAndAllowWhileIdle(). Alarms set
with setAlarmClock() continue to fire normally — the system exits
Doze shortly before those alarms fire.
Refer Optimizing for Doze and App Standby

Does periodic notifications work when device is in sleep

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).

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.

Service is not running properly when the phone is sleeping

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/

Categories

Resources