Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.lang.SecurityException: !@Too many alarms (500) registered from pid 10790 uid 10206

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: !@Too 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.

like image 355
Manpreet Patil Avatar asked Mar 30 '15 11:03

Manpreet Patil


1 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);     }  
like image 151
sagiema Avatar answered Oct 17 '22 08:10

sagiema