Android Job scheduler behavior when device goes for deep sleep - android

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.

Related

How to use alarm in Android Pie

i'm making an app for events and users can set alerts to the events they want. I use the AlarmManager for this, and the problem is on Android 9(Pie), that it seems blocking alarms and the notifications is not showing anymore.
For Android <= 8 there aren't problems.
Any tip/solution here?
Thanks
Alarms do not fire when the device is idle in Doze mode. Any scheduled alarms will be deferred until the device exits Doze. If you need to ensure that your work completes even when the device is idle there are several options available. You can use setAndAllowWhileIdle() or setExactAndAllowWhileIdle() to guarantee that the alarms will execute. Another option is to use the new Schedule tasks with WorkManager, which is built to perform background work either once or periodically. For more information, see Schedule tasks with Schedule tasks with WorkManager.
Ref: Android Developer.

Doze Mode, Battery Optimization whitelist, AlarmManager more frequent than 9 mins

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.

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

Android - run job in Firebase job scheduler at specific date and time

I am using AlarmManager in our app to set alarms that are set at specific date and time. Now recently few users of our app are complaining that these alarms are not popping up. Also, in Android O guidelines, it is mentioned that app should not run any background service and instead should switch to Firebase JobDispatcher. I have following 2 questions
In our app, we do not do any background task except to show notification to user at the specified time and date. Even in this case, should we switch to Firebase Jobdispatcher?
In case we do need to switch to JobDispatcher, how can the Job be set to run at exactly specific date and time?
Because you're not doing any background tasks like network requests or long running CPU operations, I think you should continue using Alarm Manager.
Now recently few users of our app are complaining that these alarms are not popping up.
This is because when doze mode triggers, it is not guaranteed that your alarms will be triggered(see this).
What you can do is use setAndAllowWhileIdle() or setExactAndAllowWhileIdle() methods from AlarmManager class as per your requirement for API level >= 23.
According to the documentation these are appropriate for notification purposes.
setAndAllowWhileIdle() documentation:
Like set(int, long, PendingIntent), but this alarm will be allowed to
execute even when the system is in low-power idle modes. This type of
alarm must only be used for situations where it is actually required
that the alarm go off while in idle -- a reasonable example would be
for a calendar notification that should make a sound so the user is
aware of it. When the alarm is dispatched, the app will also be added
to the system's temporary whitelist for approximately 10 seconds to
allow that application to acquire further wake locks in which to
complete its work.

Is it because of Doze mode in android, I can never create an accurate alarm clock app using AlarmManager?

I am using AlarmManager, trying to create an Alarm app for android.
I noticed that setRepeating was not working when the phone sleeps.
So, I tried setExactAndAllowWhileIdle.
But, I read this:
Unlike other alarms, the system is free to reschedule this type of alarm to happen out of order with any other alarms, even those from the same app. This will clearly happen when the device is idle (since this alarm can go off while idle, when any other alarms from the app will be held until later), but may also happen even when not idle. Note that the OS will allow itself more flexibility for scheduling these alarms than regular exact alarms, since the application has opted into this behavior. When the device is idle it may take even more liberties with scheduling in order to optimize for battery life.
I need accurate timings like an alarm clock. A user sets it for 6:00 am then ringing at 6:01 or 6:02 would be wierd!
Not ringing at all because the phone is idle is catastrophic!
What can I do now?
Do not use repeating alarms for this purpose. They are not accurate/reliable enough. Schedule one alarm using set() or setExact() (depending on your target API level). When that alarm goes off, set the next one.
NOTE: Make sure that you use an alarm type that will wake the phone:
RTC_WAKEUP or
ELAPSED_REALTIME_WAKEUP

Categories

Resources