Get List of Active Pendingintents in Alarmmanager

Get list of active PendingIntents in AlarmManager

adb shell dumpsys alarm > dump.txt

dump.txt:

Current Alarm Manager state:

Realtime wakeup (now=1309361618777):
RTC_WAKEUP #5: Alarm{4822f618 type 0 com.google.android.gsf}
type=0 when=1309882326582 repeatInterval=522747000 count=0
operation=PendingIntent{47dd3740: PendingIntentRecord{4822aeb8 com.google.android.gsf broadcastIntent}}
...
RTC #5: Alarm{4810f9d8 type 1 com.tmobile.selfhelp}
type=1 when=1309445979715 repeatInterval=86400000 count=1
operation=PendingIntent{4815a5c8: PendingIntentRecord{4810f960 com.tmobile.selfhelp startService}}
RTC #4: Alarm{4810f668 type 1 com.tmobile.selfhelp}
type=1 when=1309445959620 repeatInterval=86400000 count=1
operation=PendingIntent{480996e8: PendingIntentRecord{480214a0 com.tmobile.selfhelp broadcastIntent}}
...

Elapsed realtime wakeup (now=2110632):
ELAPSED_WAKEUP #5: Alarm{481c24e0 type 2 com.google.android.apps.maps}
type=2 when=2147485512925 repeatInterval=0 count=0
operation=PendingIntent{47d1d3a8: PendingIntentRecord{481a2600 com.google.android.apps.maps broadcastIntent}}
...
ELAPSED #1: Alarm{4829ce98 type 3 android}
type=3 when=2512653 repeatInterval=0 count=0
operation=PendingIntent{47eabda8: PendingIntentRecord{47f20250 android broadcastIntent}}
ELAPSED #0: Alarm{480f0198 type 3 com.mixzing.basic}
type=3 when=2439998 repeatInterval=0 count=0
operation=PendingIntent{48100dd8: PendingIntentRecord{480ff5a0 com.mixzing.basic broadcastIntent}}

Broadcast ref count: 0

Alarm Stats:
com.google.android.location
3ms running, 1 wakeups
1 alarms: act=com.google.android.location.ALARM_WAKEUP flg=0x4
com.google.android.gsf
274ms running, 4 wakeups
1 alarms: flg=0x4
1 alarms: act=com.google.android.intent.action.GTALK_RECONNECT flg=0x4
2 alarms: act=com.google.android.intent.action.GTALK_HEARTBEAT flg=0x4
...
-------------------------------------------------------------------------------

Android: Get all PendingIntents set with AlarmManager

You need to create your pending intent and then cancel it

 AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

Intent updateServiceIntent = new Intent(context, MyPendingIntentService.class);
PendingIntent pendingUpdateIntent = PendingIntent.getService(context, 0, updateServiceIntent, 0);

// Cancel alarms
try {
alarmManager.cancel(pendingUpdateIntent);
} catch (Exception e) {
Log.e(TAG, "AlarmManager update was not canceled. " + e.toString());
}

Get list of registered Pending Intents in Android OS

1 How can I query the OS for the Pending Intents I registers?

I'm not sure you can, but you can check if a specific PendingIntent is registered or not like this :

private boolean checkIfPendingIntentIsRegistered() {
Intent intent = new Intent(context, RingReceiver.class);
// Build the exact same pending intent you want to check.
// Everything has to match except extras.
return (PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_NO_CREATE) != null);
}

2 Will it cancel all pending intents with same action, or does it have to both same action AND extra data?

It will cancel all the PendingIntent that are resolved to be equal.

What exactly does equal means ?

The java doc of android says:

Determine if two intents are the same for the purposes of intent
resolution (filtering). That is, if their action, data, type, class,
and categories are the same. This does not compare any extra
data included in the intents.

You can read at the 7391 line here : https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/content/Intent.java

To sum up, all PendingIntent that are build exactly the same except extras will be cancelled.

Pending Intent and Alarm Manager

It's process life-cycle bug in which system may kill process when app goes in background to reclaim memory

You need to schedule JobService for receiving job whether application is active or not

from official document of Processes and Application Life Cycle

A common example of a process life-cycle bug is a BroadcastReceiver
that starts a thread when it receives an Intent in its
BroadcastReceiver.onReceive() method, and then returns from the
function. Once it returns, the system considers the BroadcastReceiver
to be no longer active, and thus, its hosting process no longer needed
(unless other application components are active in it). So, the system
may kill the process at any time to reclaim memory, and in doing so,
it terminates the spawned thread running in the process. The solution
to this problem is typically to schedule a JobService from the
BroadcastReceiver, so the system knows that there is still active work
being done in the process.

Here is example you can follow to complete your requirement

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.

Can I get all current intents setted by AlarmManager

Check this thread. Unfortunately, it seems that this is only possible using dumpsys.



Related Topics



Leave a reply



Submit