From my understanding, if I wish to create an exact repeating alarm (regardless if the device is in idle mode or not) using the AlarmManager Class, I am required to use a different scheme depending on the Android version installed. As per my readings, I would need to use setRepeating with RTC_WAKEUP for an API up to 18, setExact with manual re-scheduling RTC_WAKEUP for an API between 19 and 22, and finally setExactAndAllowWhileIdle with manual re-scheduling for an API >= to 23.
How should I handle all cases? Should I verify the API version and then program the Alarm accordingly?
Or is there a Support Library I could use for backward compatibility, which would work for all scenarios?
If I am required to use the first alternative above, how do I cancel the Alarms? Do I need to use a similar scheme, in which I would verify the API version used, and have different code executed for the cancellation, corresponding to the API installed?
How should I handle all cases? Should I verify the API version and then program the Alarm accordingly?
If you wanted, you could use set() on pre-19 versions of Android and keep the manual rescheduling consistent for all versions, rather than using manual rescheduling on some and automatic scheduling on others.
Also note that on Android P, I would expect even setExactAndAllowWhileIdle() to not be exact, if your app falls into a non-Active app standby bucket.
Or is there a Support Library I could use for backward compatibility, which would work for all scenarios?
There is AlarmManagerCompat, which offers a backwards-compatible implementation of setExactAndAllowWhileIdle().
how do I cancel the Alarms? Do I need to use a similar scheme, in which I would verify the API version used, and have different code executed for the cancellation, corresponding to the API installed?
Since you cancel by PendingIntent, you would only need different cancellation logic if you use different PendingIntent structures. My guess is that you could use the same PendingIntent for all scenarios, in which case your cancel() logic would be the same for all scenarios.
Related
I am working on an android app. In which, I want to automate Notification. The way I am thinking is first,
Fetch data from the server, then
Store in Room DataBase, then
Get data from RoomDb and then Display Notification.
Repeat this every day at least once.
Now, I want this work done in the background under any condition. That is, whether the app in the background or whether the app is closed or whether the phone is restart.
So in any situation, Fetch data→Store it→Display Notification.
I found many android background processing libraries. Such as AlarmManager, JobScheduler, BroadcastReceiver, JobIntentService, Firebase Job Dispatcher, WorkManager, etc. I am working on API 19 to API 28 or higher. These libraries have limitations and having challenges in background processing.
So, which library will be suitable for me to build an Automate Notification which works well on API 19 to API 28 or higher.
You can use Jetpack WorkManager. It is backwards compatible up to API 14.
WorkManager internally uses JobScheduler on devices with API 23+
and a combination of BroadcastReceiver + AlarmManager on devices with API 14-22.
Ensures task execution, even if the app or device restarts.
We notice that AlarmManagerCompat alone, isn't a reliable way to implement alarm/ reminder feature in our app, due to different AlarmManager behaviour in different version of OS. (For instance, Doze mode)
Initially, we plan to use Evernote's android-job library, to help us implement alarm/ reminder feature in our app.
However, along the way, we also notice that Google just release WorkerManager.
So far, WorkerManager works well for us, when we run some one-time background jobs (Almost immediate, with internet connectivity constraint) after the app quit.
We have plan to use WorkerManager to implement alarm/ reminder feature.
I was wondering, how reliable is WorkerManager to implement such feature? Has anyone try it out? We are targeting API 15 and above.
WorkManager is not appropriate for anything that must fire at a specific time as jobs, including those used by WorkManager or android-job, will not fire while the device is dozing.
For exact timing, you should absolutely be using AlarmManagerCompat and specifically, setExactAndAllowWhileIdle() which fires an alarm at exactly the specified time on all API levels.
As your exact timed alarm can and will happen while the device is dozing, your app should not require network connectivity to post your alarm/reminder notification. Ideally, the information should be in the PendingIntent itself and not even need any database fetch/etc.
I'm trying to deliver notifications in my app at specific times.
I know about Doze and how nothing bypasses its restrictions except AlarmManager.setAlarmClock() because even even setExactAndAllowWhileIdle is not really exact.
I really hoped I could deliver the notifications on time if I use setAlarmClock however it looks like even this method doesn't guarantee you precision.
setAlarmClock not exact in android marshmallow
So as I understand there are two different kinds of batching occurs when it comes to alarms. The general one occurs above api level 18 and the other occurs during Doze which happens in above api level 23. Please correct me if I'm wrong on this.
If this is true then how am I able to by avoid both and deliver the notification at the exact time I set it to?
Also I had a look at this library which does the api level based branching for me however it still use methods like setExactAndAllowWhileIdle which is not exact as I mentioned it above.
PS:this article and its continuation explain this stuff well.
What is JobScheduler ? which type of android apps using this JobScheduler and why ? Please feedback with real example so that I could understand.
Here is a short summary:
1) AlarmManager.- Use it to post a notification or set off an alarm at a very specific time. Use this for executions that do not depend on condition.
2) JobScheduler.- Allows you to have execute jobs based on conditions. This is recommended if your app targets API>21.
3) JobDispatcher.- Similar behavior as JobScheduler, used as a JobScheduler-compatibility layer if your app targets versions lower than API<21. Note that this needs internet for real time execution, any task not executed because of internet not being available will be executed when internet becomes available.
I want to track users in specific period and times of days. I start alarm manager in every 2 minutes (i get periodic time from server and this is dynamic in my application) and try to get location about one minute, after that i stopped getting location and i save location taken on DB. anyway, this approach run very well but in api level 23 and above that, my application for doze and standby mode cannot run well and not call alarms in specific time! I used setExactAndAllowWhileIdle method for api level 23 and above that but not worked well.
The documents said, i can't use more alarms in doze and standby mode.
My question is, how can track user in android 6 and above?
While working with alarm in doze, use setAlarmClock() instead of set() as it is specifically designed for AlarmClocks, so it can run even in doze as well.
Alternatively,
Have you ever heard of Firebase-job-dispatcher ?
Firebase JobDispatcher is an open-source library that provides an API
similar to JobScheduler in the Android platform. Firebase
JobDispatcher serves as a JobScheduler-compatibility layer for apps
targeting versions of Android lower than 5.0 (API level 21).
Firebase JobDispatcher supports the use of Google Play services as an
implementation for dispatching (running) jobs, but the library also
allows you to define and use other implementations: For example, you
might decide to use JobScheduler or write your own, custom code.
Because of this versatility, we recommend that you use this Firebase
JobDispatcher if your app targets a version of Android lower than 5.0
(API level 21).
You should go for it. They have got pretty good configuration techniques as well.