Check If alarmManager has already been running
boolean alarmUp = (PendingIntent.getBroadcast(context, 0,
new Intent("com.my.package.MY_UNIQUE_ACTION"),
PendingIntent.FLAG_NO_CREATE) != null);
In the above statememnt "com.mypackage" is package name where as "MY_UNIQUE_ACTION" is class name where you handle AlarmManager.
The key here is the FLAG_NO_CREATE which as described in the javadoc: if the described PendingIntent does not already exists, then simply return null (instead of creating a new one)
so from the above statement you can know that the boolean value returns true if AlarmManager class is running else false.
You can get package name by various method
- Simply by typing the package name.
- As described in this link
Check if AlarmManager exists always returning false
Maybe, alarmUp
is always false because your are using a different Intent
to compare them
Checking if they exist:
boolean alarmUp = (PendingIntent.getBroadcast(context, 100, new Intent(), PendingIntent.FLAG_NO_CREATE) != null);
Creating the alarm:
Intent intent1 = new Intent(context, Notification.class);
intent1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 100, intent, PendingIntent.FLAG_UPDATE_CURRENT);
As you can see, Intent
use in both statment are different.
Try to check as below:
Intent tempIntent = new Intent(context, Notification.class);
tempIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
boolean alarmUp = (PendingIntent.getBroadcast(context, 100, tempIntent, PendingIntent.FLAG_NO_CREATE) != null);
By the way
All alarms are destroyed during a reboot... So, you should register your BroadcastReceiver
to receive BOOT_COMPLETED
events. This way, when you receive BOOT_COMPLETED
event, you know that your device was rebooted and no alarm is active... Then, you crete them again.
Unable to check if alarm has been set by AlarmManager
In order for this check to work, you need to be absolutely sure that the PendingIntent
only exists when the alarm is set. There are 2 things you can do to ensure that is so:
1) When testing your code, make sure that you uninstall your application and then reinstall your application before testing it. Uninstalling your app will remove any PendingIntent
s that your app might have created that are still pending.
2) When you cancel the alarm, make sure that you also cancel the PendingIntent
. You can do this with
Intent alarmIntent = new Intent(MainActivity.this, AlarmReceiver.class);
final PendingIntent pendingIntent =
PendingIntent.getBroadcast(MainActivity.this, 0, alarmIntent,
PendingIntent.FLAG_NO_CREATE);
if (pendingIntent != null) {
pendingIntent.cancel();
}
Is there any way to check if an alarm is already set?
First of all, a little tutorial on how to access previously created alarms:
You can differentiate between alarms by creating each with a unique id such as:
Intent intent = new Intent(this, AlarmReceiverActivity.class);
PendingIntent pi = PendingIntent.getActivity(this,UNIQUE_ID_GOES_HERE, intent, 0);
AlarmManager am = (AlarmManager)getSystemService(Activity.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, triggerAtMillis ,pi);
When you want to access this alarm, you have to create the same PendingIntent with the same unique id. For example, the following will only access an alarm that you created with PendingIntent id 1234. Then it will cancel the previous one and reset it.
Intent intent = new Intent(this, AlarmReceiverActivity.class);
PendingIntent pi = PendingIntent.getBroadcast(this, 1234, intent, 0);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, triggerAtMillis ,pi);
The idea is simple. Keep track of the id's and then use them to access their respective alarms. If you create multiple alarms with same id, the most recent one will cancel the previous.
Coming to your main problem, instead of checking if your alarm is active each time you launch your application, just re-set it in your Activity's onCreate()
method. with the same PendingIntent as I described above. This saves you all the hassle of checking if the alarm is previously set or not. Since your aim is to keep the alarm alive, it won't hurt to override the previously set one everytime you launch the application. Just make sure you use the same id to create your PendingIntent.
Do not forget to check if the time for your alarm has already passed or not in order to avoid trying to set an alarm for a past time, which will trigger it immediately.
Let us consider another case: when you turn off your device, all your alarms will be cancelled. This leaves you no option but to set them again at reboot. To do that, you will have to use a BroadcastReceiver.
This answer will help you on how to do that. Just recreate your alarm in the onReceive() method of your BroadcastReceiver as suggested above.
How do I check if AlarmManager has an alarm set with FLAG_ONE_SHOT
I created a small test program to verify this behaviour. If you create a PendingIntent
using FLAG_ONE_SHOT
and then pass this to the AlarmManager
, it looks like Android "consumes" the PendingIntent
immediately so that it no longer exists (because it is a "one-shot", it can only be used once). I would have thought this would happen when the alarm actually triggers, but it looks like that isn't the case.
You learn something new every day :-)
To solve your problem, I would just remove the FLAG_ONE_SHOT
as you probably don't need it (just pass 0
as the "flags" argument). If you set the alarm more than once, you can use FLAG_UPDATE_CURRENT
if you set the alarm with different extras each time (but it looks like you aren't using any extras, so you probably don't need this). I don't think that you need FLAG_ONE_SHOT
for what you are trying to do.
AlarmMenager Checking if alarm already fired
First thing, stop relying on AlarmManager
alone to save and manage alarms. There are many scenarios where alarms will be cleared or delayed etc.
Have a SQLite table etc. to properly track alarms, along with created,scheduled and triggered time stamps.
______________________________________________________________________
| id | name | repeating | time | interval | set_at | triggered_at |
______________________________________________________________________
| 0 | abc | 1 | 2394000 | 36000 | 2003900 | 1800094 |
______________________________________________________________________
Then:
Implement a boot intent receiver to read this table and schedule alarms for each record.
When an alarm setting is updated, update it in database and re-schedule that alarm.
when an alarm is triggered, update time stamps in corresponding database record.
Check if AlarmManager task is in progress
Will it reset the time and I'll have to wait for 10 mins to receive an event?
Yes it will. As per doc:
If there is already an alarm scheduled for the same IntentSender, it will first be canceled.
And as per
Is there a way to check if my alarm task schedule is set?
Yes, there is several solutions, which you can check.
And, btw, be aware that setRepeating
is inexact.
Note: as of API 19, all repeating alarms are inexact. If your application needs precise delivery times then it must use one-time exact alarms, rescheduling each time as described above. Legacy applications whose targetSdkVersion is earlier than API 19 will continue to have all of their alarms, including repeating alarms, treated as exact.
Check if an alarm manager is running (not working correctly)
When you fetch a pending intent to see if it exists, you need to recreate it exactly as you did before. So you'll need to pass the original request code to the alarmIsRunning() method.
Here is an extract from one of the methods I use for reference:
private fun doesPendingIntentExist(requestCode: Int, intent: Intent): Boolean {
val tempPendingIntent = PendingIntent.getBroadcast(context,
requestCode, intent,
PendingIntent.FLAG_NO_CREATE)
tempPendingIntent?.cancel()
return tempPendingIntent != null
}
TL;DR: You need to pass the original request code to the PendingIntent.getBroadcast()
method.
Related Topics
How to Hide Soft Keyboard on Android After Clicking Outside Edittext
Android Drawing Separator/Divider Line in Layout
How to Display a List View in an Android Alert Dialog
Android Fragments and Animation
Android Update Activity UI from Service
Disable Scrollview Programmatically
How to Add Stacktrace or Debug Option When Building Android Studio Project
Set Transparent Background of an Imageview on Android
How to Check If Alarmmanager Already Has an Alarm Set
Difference and Uses of Oncreate(), Oncreateview() and Onactivitycreated() in Fragments
Failed to Load Appcompat Actionbar with Unknown Error in Android Studio
How to Get an APK File from an Android Device