How do you cancel a specific alarm manager after app is restarted? - android

I'm creating an app that, after receiving a text from a certain number, starts a repeating alarm using AlarmManager. The AlarmReciever plays an alarm sound for thirty seconds and then the alarm repeats every five minutes. I want to cancel the AlarmManager when the app is closed and restarted by the user but I have to use the same instance of the alarmIntent to cancel it.

I have to use the same instance of the alarmIntent to cancel it.
No, you have to use an equivalent PendingIntent to cancel it. By "equivalent", I mean:
It is the same operation (e.g., activity, service, broadcast)
It has the same request code (2nd parameter to methods like getActivity())
It has an equivalent Intent
By "equivalent Intent", I mean that all the routing information is the same (component, action, data, MIME type, categories). Extras do not matter.
You need to hold onto enough information in a persistent data store (e.g., file) to be able to create an equivalent PendingIntent to pass to cancel() on AlarmManager.

Related

Android AlarmManager why calling BroadcastReceiver?

I'm currently working on an app that handles alarms. I have reach the point where I can set the alarms using the AlarmManager and everything seems to work fine, but.. In all the examples that I found, and even in the Android official docs, I have seen people using a BroadcastReceiver for the PendingIntent, and then, calling an activity or whatever they need when the alarm fires. However, I have try to just pass a simple activity to the PendingIntent for the AlarmManager like this:
Intent intent = new Intent (getApplicationContext(), AlarmActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity (this, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set (AlarmManager.RTC_WAKEUP, timeToTrigger.getTimeInMillis(), pendingIntent);
And after testing alarms in several contexts (app in foreground, app not running, etc..) I found that the activity is always been called correctly.
So, my doubt is as simple as: Why do people use a BroadcastReceiver and in the onReceive method call an activity if you can just simple call the activity directly?
Android frowns on this behaviour. You shouldn't interrupt the user if he is doing something else. This is why you don't want to launch an Activity from AlarmManager. Usually, you launch a BroadcastReceiver, which, if it wants to get the user's attention, will post a Notification. The user can then open the app via the Notification whenever he wants to.
Also, often you just want to perform some background process (like fetching data from a server, or updating some statistics), which doesn't require any user-interaction. In this case you would also launch a BroadcastReceiver or Service and not an Activity.
Starting with Android 10 there are more restrictions about background apps launching activities. Therefore, with current versions of Android it has become more difficult to do this. See https://developer.android.com/guide/components/activities/background-starts
So basically, even though it does work, it is not considered "respecting the user" and it probably won't work in the future.

android - What do I need to keep to persist alarm after reboot?

I am currently developing an android application where I need to setup persistent alarms that will fire on a specific date and time and show a notification. It works well but the system clears all alarms upon rebooting.
From other questions I know that if I create a BroadcastReceiver forBOOT_COMPLETED I can rearm canceled alarms. My question is: What information about those alarms I need to keep in order to rearm them when needed?
Some people say that I need to persist all the Intent extras and the fire datetime in order to recreate the PendingIntent upon rebooting.
Others say that if I only persist the requestCode for the PendingIntent, after reboot I can use this code to get the canceled PendingIntent and rearm the alarm, because when the device reboots the PendingIntent's are just canceled instead of deleted.
Which one is right way to do it?
PendingIntents will not persist after reboot, so to be safe just restart your alarms in the BroadcastReceiver with all the intent extras that you make when you first initialized the alarm, and keep the requestcode the same.

Start alarm in broadcastreceiver and turn off in service

I think I have a design issue, but I will ask you guys the question.
My applications receives a broadcast in xbroadcastreceiver, i check some conditions and if true, I start a service, say zservice, using Alarm Manager with PendingIntent. Now in zservice, everytime when it is triggered by the alarmmanager, I check some other conditions and based upon a specific condition I need to cancel the alarm, I know alarmManager.cancel(pendingIntent);
will cancel the alarm, but my issue is how to get a access to the pendingIntent as it was in the xbroadcastreciever.
I have tried send pendingIntent to service but so far I am not successful so that when I need, I can turn the alarm off.
Hope this logic makes sense.
I know alarmManager.cancel(pendingIntent); will cancel the alram, but my issue is how to get a access to the pendingIntent as it was in the xbroadcastreciever.
Create an Intent with the same routing information (component, action, categories, MIME type) as the original. Create the same type of PendingIntent from this Intent as before (e.g., getService()). Use that PendingIntent with the cancel() call.

Controlling Alarm from 2 diff applications - Android

I need help in my android app development.
It goes something like this,
I will be having two separate applications (2 projects). In one application, i have to start a repeating alarm and in the other application i have to cancel the same alarm that was started in the first application.
The Android documentation says, the same pending intent and the intent object that was used to start the alarm
should be used the cancel the alarm.
So in this scenario, the pending intent and the intent object that was used to start the alarm will belong to application1 so i cannot used the same objects in application2
How do I proceed?
In summary -
The problem is, I need to start a repeating alarm from one application and i have to cancel the same alarm from another application.
Can this be done. If so, How?
Thanks in advance.
ifreeman
It is not that straightforward. Only original activity can cancel the alarm.
So I think you can configure a custom broadcast. When the second activity needs to cancel an alarm it will send this broadcast. The first activity will be listening to the broadcast and cancel the appropriate alarm on receiving it.
I guess you can do. Alarms are considered as same if intents passed to them via pending intent are same. filterEquals method of Intent class defins if intents are same or not. If intents are same then alarms are same so u can cancel that alarm. Check once.

Activity to trigger and cancel a AlarmManager

I am trying to develop an app where it locks down the Activity and starts a service which will set an AlarmManager to setRepeating() trigger to another Service which will send a SMS containing the phone's location.
I have achieved the periodic sending of the SMS. However, I now want to cancel the AlarmManager when I finish() the lockdown activity. Please help me as I cant seem to understand the approach to address this.
Program flow:
Lockscreen (Activity trigger Service) --> AlarmManager (in Service class) --> Coordinate (Another Service that send sms)
Call cancel() on AlarmManager with an equivalent PendingIntent to the one you used to register the alarm in the first place. By "equivalent" I mean that it is the same type of PendingIntent (activity, service, broadcast) and wraps an Intent that is the same on all routing elements (component, data, MIME type, categories).

Categories

Resources