I am developing a clock app that needs to get the next Alarm triggering time. By "Alarm" I mean the noisy ones to wake up. I do this with
AlarmManager.AlarmClockInfo aci = ((AlarmManager) getSystemService(Context.ALARM_SERVICE)).getNextAlarmClock();
The problem is that my app is catching Tasker "alarms" (that I have no idea where they come from), instead of the usual Clock alarms.
How do I catch a "true" noisy clock alarm? Or how do I tell AlarmManager to ignore Tasker alarms?
AlarmManager is for setting some actions to be performed at certain moment by apps. This may be "true noisy alarm" or any other action, e.g. showing reminder notification or do some sync with servers in background. check out some related DOC
There is no such thing like "system alarm" - you have some clock app installed on your device and it have feature to set "true noisy alarm" in the future. It may use AlarmManager for getting informed that time for making noise comes, but may also use any other mechanism, like WorkManager
So there is no way/API for getting information about "true noisy alarms" set in system. Because such thing doesn't exists, alarm is a feature of app, you may have few clock apps, you may uninstall all available on device. One and only chance for getting list of "true noisy alarms" is to communicate with setting-alarms-app in any way (broadcast? aidl?), I very doubt any app this type is providing any api for this check...
Related
I'm having trouble deciding whether to run some recurring background work with Alarm Manager or Work Manager:
The work is going to consist of Room Database operations so I'll need access to Dao to complete my work.
It is going to be recurring at fixed intervals (hourly, daily, weekly, monthly, etc.)
I need to set a start date and time for the recurrence intervals.
the work will recur until canceled by the user
If the user is using the app when the work is supposed to be scheduled, I want the work to be done immediately. If the user is not on the app (app is in the background or device is turned off), I don't care if the work is done after the scheduled time as long as it is at least started by the next time the user opens the app.
the work needs to continue as scheduled after device reboots and app restarts.
For recurring background work, AlarmManger isn't suitable. As the name implies, it's intended to notify the system of an event at a precise time. Just like a physical alarm that wakes a person up even if the person sleeps, AlarmManager will wake up the device from doze mode which will result in more power usage. it is suitable for suitations like setting remainders such as for calender events which the users probably set by themselves.
On the other hand, WorkManager is intended to carry out background processing or work that would persist. Workmanager is much more efficient for recurring task especially as it allows you set constraints to determine when it should start or stop the background work.
check the link form the offical documentation on WorkManger:
workmanager architecture
tabular comparison between the two
It mostly depends on how important your task is.
https://developer.android.com/guide/background is a really good entry point to help you choose what you should work with.
WorkManager is the modern, universal approach of handling background work and it fits for most use-cases, it automatically reschedules work after a device restart or an application crash, and it is very efficient in terms of battery usage.
As WorkManager does respect Android's doze mode, it does not guarantee, that the work will be done exactly on time, though it does guarantee, that your work will be done within a certain time frame.
On the other hand, AlarmManager is capable of running work precisely on time. But this means that the device will wake up when your work scheduled with AlarmManager is coming due. This will drain battery and your app will probably show up as battery-draining in the Device Health board.
But as stated in the article above, prefer using WorkManager if possible. AlarmManager should only be used for e.g. a time-sensitive calendar notification.
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.
I have an app which allows users to schedule alarms to sound at certain times, repeating at intervals of their choosing. I am using JSON to persist the alarm details, using SharedPreferences as storage.
I am using AlarmManager to schedule when my app should be notified that an alarm should sound to notify the user. I am currently using the setRepeating() method of AlarmManager, supplying the interval provided by the user. This works well, and in theory the app would never need to update the JSon which stores the next alarm time, as AlarmManager will just reschedule the next alarm time using the interval.
However, my thinking is that when the device is rebooted, I will need to supply a up to date alarm time to AlarmManager to avoid AlarmManager thinking an alarm has been missed as this is not necessarily the case.
So, what's the best way to do this?
update the JSon next alarm time when the alarm is sounded, even though this may not be necessary (setRepeating() handles this as long as there is no reboot)?
register for and listen for shutdown broadcasts and update JSon then (this raises questions - just how long will the app get to calculate and write alarm details to storage given that the phone is shutting down)?
don't update the JSon but add logic to the object which is woken by the AlarmManager to decide if the alarm just broadcast is valid and the user should be alerted?
I'm sure any of the above will work, but I can't decide which is the nicest way to do it.
This seems mostly a matter of choice. The problem you note parallels a general problem seen in Linux laptops and solved by anachrond. In my opinion, I would simply update the time and store it in SharedPreferences every time the event is received. Trying to listen for when the system shuts down might not be entirely reliable (what happens when your users -- probably drunk college students -- drop their device and the battery flies out?). Instead, I believe the best thing to do in this scenario would be to -- each time the alarm fires -- recalculate the time to send the next one, store it somewhere, and upon boot schedule appropriately.
When an app sets a repeating alarm and from the users point of view the phone is in normal mode with an alarm in the notification bar what is happening with the code of the app? I assume the values of all the variables are stored in the phone memory in such a way that when the alarm wakes up the original state is restored. Does setting an alarm impose much more demand on the battery?
When an app sets a repeating alarm and from the users point of view the phone is in normal mode with an alarm in the notification bar what is happening with the code of the app?
AlarmManager has nothing to do with the AlarmClock application. There is no "alarm in the notification bar" unless you put something there yourself, which would be a bit unusual for an app employing AlarmManager.
Assuming you are referring to AlarmManager, "what is happening with the code of the app" is it better be shut down. The point behind AlarmManager is so you do not have to keep any code in memory just to watch the clock tick by.
I assume the values of all the variables are stored in the phone memory in such a way that when the alarm wakes up the original state is restored.
That is absolutely incorrect. AlarmManager does nothing of the sort. And, a well-written app using AlarmManager will get the heck out of memory when it is not delivering any immediate value. If you need data to persist between alarms, use databases or files.
Does setting an alarm impose much more demand on the battery?
A _WAKEUP alarm will have an impact on the battery proportional to the frequency with which the alarm goes off. If the alarm is nice and infrequent (e.g., user configured to every 15 minutes), the alarm itself will have little impact, but what you do when the alarm goes off might.
I'm new to Android development, so I might be missing something obvious. I want to launch an Activity when the user's phone clock hits a specified time (similar to an alarm). However, I'm not sure how I would go about doing this as constant polling of the clock seems inefficient and a waste of resources. Do I need to capture broadcast events from the clock, or use PendingIntents? If someone could point out some SDK methods/services I should read about, it would be much appreciated.
Thanks.
Take a look at the docs for android.app.AlarmManager.
This class allows your application to schedule PendingIntents for broadcast at specific times, which sounds like exactly what you're looking for. Just schedule a PendingIntent that launches the desired application.
Be aware that when your alarm fires, the phone will be prevented from sleeping until (and only until) onReceive() finishes executing. If you need to keep the phone awake longer, you may need to implement your own wake lock.