Home » Android » android – java.lang.SecurityException: [email protected] many alarms (500) registered from pid 10790 uid 10206

android – java.lang.SecurityException: [email protected] many alarms (500) registered from pid 10790 uid 10206

Posted by: admin April 23, 2020 Leave a comment

Questions:

I’m getting this error at the time of Schedule alarm using Alarm Manager

am.setExact(AlarmManager.RTC_WAKEUP, timeMillis, pendingIntent);

Error is as follow

java.lang.SecurityException: [email protected] many alarms (500) registered from pid 10790 uid 10206
at android.os.Parcel.readException(Parcel.java:1540)
at android.os.Parcel.readException(Parcel.java:1493)
at android.app.IAlarmManager$Stub$Proxy.set(IAlarmManager.java:206)
at android.app.AlarmManager.setImpl(AlarmManager.java:428)
at android.app.AlarmManager.setExact(AlarmManager.java:376)

Why this error is coming and how we can fix it.

How to&Answers:

Unlike what the comment suggests, this might not be your fault. This started happening for us in production code somewhere mid March, this only happens on Samsung with Lollipop which only recently started to be rolled out.

Update:
This issue finally happened on one of the phones we have available.

like @goncalossilva said the problem is due to use of FLAG_CANCEL_CURRENT, it seems that Samsung introduces a cap of 500 on the amount of alarms and no other vendor have this limit.

when creating a PendingIntent with FLAG_CANCEL_CURRENT it will cancel the pending intent (obviously) won’t cancel the alarm (also obvious), later if you cancel the alarm using the new pending intent it won’t cancel the alarm (less obvious as Intent.filterEquals should be true). That being said, because the pending intent was canceled the old alarm won’t actually fire, so there it no fear in introducing bugs by switching FLAG_UPDATE_CURRENT.

regarding the need to restart the device after changing to FLAG_UPDATE_CURRENT, you don’t have to restart you just need to wait for one of the alarms to fire so that you have a new slot for a new alarm.

you can try this code to reproduce the issue, then change to FLAG_UPDATE_CURRENT to see what happens.
you should also run "adb shell dumpsys alarm" to see all the generated alarms

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

    for (int i = 0; i<1000; i++)
    {
        Intent intent = new Intent("FOOFOOFOO");
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
        alarmManager.cancel(pendingIntent);

        long firstTime = SystemClock.elapsedRealtime() + 1000;
        alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime, pendingIntent);
    } 

Answer:

For those encountering this problem solely on Samsung devices running Lollipop, you are probably using FLAG_CANCEL_CURRENT with your PendingIntents. Switch to FLAG_UPDATE_CURRENT (making any other adjustments, if necessary), and the problem should go away.

My completely unfounded guess is that Samsung is doing some “optimizations” with FLAG_CANCEL_CURRENT where they don’t remove the canceled PendingIntent right away but only mark it for deletion and then do it too infrequently (or not at all?).

Edit

We’ve found that devices where this problem occurs will be in a broken state (filled with PendingIntents?) until they are restarted or the app is reinstalled.

Answer:

Never use FLAG_CANCEL_CURRENT with PendingIntents that you use when setting alarms. If you want to reschedule the alarm for a different time you don’t need any flag at all; just create a duplicate PendingIntent with flags of zero and then use it to set() an alarm: this will implicitly cancel the existing alarm and then set it for the newly-specified time. If you used FLAG_CANCEL_CURRENT when you created the new PendingIntent, though, it breaks the Alarm Manager’s ability to recognize that it’s “the same” as the now-canceled PendingIntent, and you wind up with the old one hanging around, undeliverable, taking up memory and CPU. I’ve seen apps with this bug rack up literally hundreds of stale alarms in the system, enough to be a noticeable performance and memory-usage hit.

If you just want to change the extras without actually rescheduling the existing alarm, that is what FLAG_UPDATE_CURRENT is for. If you just want to reschedule or cancel the alarm, just use 0 for the flags.

Answer:

It seems that the newest Lollipop build on Samsung devices restricts the number of alarms you can register. I’ve temporarily fixed the problem in my app by only registering at most X alarms at any given time (I’ve arbitrarily chosen X = 50 but judging by the error message I believe you can go up to 499. I have not tested this however).

I’ve released a version with this temporary fix a week ago and I haven’t had this crash reported since.

Answer:

For me changing to FLAG_UPDATE_CURRENT alone did not help to get rid of the multiple entries of my pendingIntents (watched with adb shell dumpsys alarm > dump.txt).

I fixed it by changing the way I cancel those pending intents from

PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT).cancel();

to

PendingIntent pi = PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT).cancel();
alarmManager.cancel(pi);

This was necessary for .getBroadcast() and .getService(). Interestingly with .getActivity() it was not. Sadly I have no clue why this is the case.

All on a Samsung Galaxy S4 with Android 5.0.1. Perhaps this helps someone else, too.

Answer:

I fixed it using the flag: PendingIntent.FLAG_UPDATE_CURRENT

PendingIntent pendingIntent = PendingIntent.getService(
    MainActivity.this, 200, intent, PendingIntent.FLAG_UPDATE_CURRENT
);

am.setExact(AlarmManager.ELAPSED_REALTIME, realtime + 2000, pendingIntent);

I tested it into a Galaxy S4 running in Android 5.0.1.