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
Related
I am currently working with an android application that uses android job scheduler to call an api at certain interval(lets say every 4 hours).
Suppose my device is not on charge and there is no activity being done on it, so it goes to sleep after some time(lets say after 1 hour of last api call).
Now my device wakes up after 5 hours due to some activity that I did deleberatly. Will the scheduler call the api immediately(as its more than 4 hrs since last call)? or will it wait for next 3 hours to run the job?
(*I have not acquired the wake lock in this case so the device will go to sleep.)
I think you by Deep Sleep you mean Doze. When your device in doze mode your JobServices will not trigger. Periodic job can't be exact. A job is either exact or periodic. So periodic will trigger while in maintenance window between execution interval. If you running your jobs on Lollipop + with high frequency, then it's possible, that some periods are skipped, because the device is saving battery.
Check out restrictions for doze mode:
Network access is suspended.
The system ignores wake locks.
Standard AlarmManager alarms (including setExact() and setWindow()) are deferred to the next maintenance window.
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.
The system does not perform Wi-Fi scans.
The system does not allow sync adapters to run.
The system does not allow JobScheduler to run.
But you can use some hacks to make your job executes at specific time/immediately after scheduling.
I'm creating an app to connect with BT device to collect heath data (i.e.: body temperature).
The sensor sleeps for periodic time and wakes up only for limited window of time to connect.
I've tried to create AlarmManager which fires Foreground Service with setExactAndAllowWhileIdle() and it is working as expected for periods higher than 9 minutes,
but below 9 minutes it goes to doze mode and do not fire AlarmManager BroadcastReceiver.
From documentation I do not understand if adding app to battery optimalization whitelist will allow AlarmManager to trigger more offen
https://developer.android.com/training/monitoring-device-state/doze-standby#support_for_other_use_cases
For example, the whitelisted app’s jobs and syncs are deferred (on API level 23 and below), and its regular AlarmManager alarms do not fire
What are the regular alarms? is setExactAndAllowWhileIdle() regular?
Any clarification will be appreciated
EDIT:
I understand that setExactAndAllowWhileIdle() will trigger event in doze mode for periods longer than 9 minutes, question is does adding app to whitelist will allow it to trigger more often
What are the regular alarms ? is setExactAndAllowWhileIdle() regular ?
No. setExactAndAllowWhileIdle() is not regular. Regular alarm could be AlarmManager alarms set though setExact() and setWindow().
but below 9 minutes it goes to doze mode and do not fire AlarmManager
BroadcastReceiver
It has restrictions on how frequently you can set alarm.
Based on the documentation:
To reduce abuse, there are restrictions on how frequently these alarms
will go off for a particular application. Under normal system
operation, it will not dispatch these alarms more than about every
minute (at which point every such pending alarm is dispatched); when
in low-power idle modes this duration may be significantly longer,
such as 15 minutes.
You can refer to Doze restrictions which says:
Standard AlarmManager alarms (including setExact() and setWindow())
are deferred to the next maintenance window.
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
For Whitelist:
Apps available in whitelist are partially exempt from Doze and App Standby optimizations. This doesn't mean they have full access to and could perform tasks during doze mode. An app that is whitelisted can use the network and hold partial wake locks during Doze and App Standby. However, other restrictions like jobs being differed, standard alarm trigger are still imposed
Note: You should check acceptable usecases for whitelisting an app.
Google Play policies prohibit apps from requesting direct exemption
from Power Management features in Android 6.0+ (Doze and App Standby)
unless the core function of the app is adversely affected.
I'm developing an app which connects to a special device via wifi. I need to make status updates in a short interval, resp. keep the status of my special device in the app up to date. FCM is not an option. My idea is to give the user two options: Fast updates using a foreground service or "slow" updates using a periodical update mechanism to save battery.
My question is about the second option. The interval should be around five minutes. Using JobScheduler therefore is not possible. But even using the AlarmManager seems not to be an option because I'm not able to get network access during the doze maintenance windows.
I thought about using a WakefulBroadcastReceiver to receive the Intent by the AlarmManager, require a WakeLock and turn my long running Service into foreground by calling startForeground(). But it seems that the startForeground() method has no effect on the Service as long as the device stays in doze mode.
I read many pages about doze and services but have no clue how to solve my problem... Does anyone got an idea?
you should use GcmTaskService. You can schedule some interval for your operations and it would work fine even in doze mode, check more information by link
You can use setAlarmClock, but it is not recommended for your purposes.
Instead you can use setExactAndAllowWhileIdle with manual re-programming with an interval of 15 minutes.
Best way: GCM.
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'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.