Java.lang.SecurityException:! @Too muchas alarmas (500) registradas de pid 10790 uid 10206

Estoy recibiendo este error en el momento de la alarma de programa con el Administrador de Alarma

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

El error es el siguiente

 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) 

¿Por qué este error está llegando y cómo podemos solucionarlo.

A diferencia de lo que el comentario sugiere, esto podría no ser su culpa. Esto comenzó a suceder para nosotros en el código de producción en algún lugar a mediados de marzo, esto sólo sucede en Samsung con Lollipop que sólo recientemente comenzó a ser lanzado.

Actualización: Este problema finalmente ocurrió en uno de los teléfonos que tenemos disponibles.

Como @goncalossilva dijo que el problema se debe al uso de FLAG_CANCEL_CURRENT , parece que Samsung introduce un límite de 500 en la cantidad de alarmas y ningún otro proveedor tiene este límite.

Al crear un PendingIntent con FLAG_CANCEL_CURRENT cancelará la intención pendiente (obviamente) no cancelará la alarma (también obvio), más tarde si cancela la alarma utilizando la nueva intención pendiente no cancelará la alarma (menos obvia como Intent.filterEquals debe ser true ). Dicho esto, debido a que la intención pendiente se canceló la alarma de edad no se disparará, por lo que no hay miedo a la introducción de errores mediante el cambio FLAG_UPDATE_CURRENT .

En cuanto a la necesidad de reiniciar el dispositivo después de cambiar a FLAG_UPDATE_CURRENT , no tiene que reiniciar sólo tiene que esperar a que una de las alarmas para disparar para que tenga una nueva ranura para una nueva alarma.

Puede probar este código para reproducir el problema y, a continuación, cambie a FLAG_UPDATE_CURRENT para ver qué sucede. También debe ejecutar "adb shell dumpsys alarm" para ver todas las alarmas generadas

  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); } 

Para aquellos que se enfrentan a este problema únicamente en los dispositivos Samsung que ejecutan Lollipop, es probable que utilice FLAG_CANCEL_CURRENT con su PendingIntent . Cambie a FLAG_UPDATE_CURRENT (haciendo cualquier otro ajuste, si es necesario), y el problema debería desaparecer.

Mi suposición completamente infundada es que Samsung está haciendo algunas "optimizaciones" con FLAG_CANCEL_CURRENT donde no quitan el PendingIntent cancelado de inmediato, pero sólo marcarlo para la eliminación y luego hacerlo demasiado infrecuentemente (o no?).

Editar

Hemos encontrado que los dispositivos donde se produce este problema estarán en un estado roto (lleno de PendingIntent s?) Hasta que se reinicien o se reinstale la aplicación.

Parece que la nueva compilación de Lollipop en dispositivos Samsung restringe el número de alarmas que puedes registrar. He arreglado temporalmente el problema en mi aplicación sólo registrando en la mayoría de las alarmas X en un momento dado (he elegido arbitrariamente X = 50, pero a juzgar por el mensaje de error creo que puede ir hasta 499. No he probado esto sin embargo).

He publicado una versión con esta solución temporal hace una semana y no he tenido este accidente informado desde entonces.

Para mí el cambio a FLAG_UPDATE_CURRENT por sí solo no ayudó a deshacerse de las entradas múltiples de mis pendingIntents (observado con adb shell dumpsys alarm > dump.txt ).

Lo arreglé cambiando la forma en que cancelo los intentos pendientes de

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

a

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

Esto fue necesario para .getBroadcast() y .getService() . Curiosamente con .getActivity() no lo era. Lamentablemente no tengo ni idea de por qué este es el caso.

Todo en un Samsung Galaxy S4 con Android 5.0.1. Quizás esto ayude a alguien más, también.

Nunca utilice FLAG_CANCEL_CURRENT con PendingIntents que utilice al configurar alarmas. Si desea reprogramar la alarma por un tiempo diferente, no necesita ninguna bandera en absoluto; Basta con crear un duplicado PendingIntent con banderas de cero y luego usarlo para establecer () una alarma: esto cancelará implícitamente la alarma existente y luego la fijará para el tiempo recién especificado. Si utilizó FLAG_CANCEL_CURRENT cuando creó el nuevo PendingIntent, sin embargo, rompe la capacidad del Administrador de alarmas para reconocer que es "igual" que el ahora cancelado PendingIntent, y se enrolla con el antiguo colgando, no se puede entregar, ocupa la memoria Y la CPU. He visto aplicaciones con este estuche de bugs hasta literalmente cientos de alarmas viciadas en el sistema, lo suficiente como para ser un rendimiento notable y el uso de memoria de éxito.

Si solo desea cambiar los extras sin reprogramar la alarma existente, es para lo que FLAG_UPDATE_CURRENT está. Si sólo desea reprogramar o cancelar la alarma, utilice sólo 0 para las banderas.

Lo arreglé usando el 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); 

Lo probé en un Galaxy S4 corriendo en Android 5.0.1.

  • AlarmManager setExact con WakefulBroadcastReceiver a veces no es exacto
  • Alarmmanager.setRepeating dispara Inmediatamente
  • AlarmManager no funciona en varios dispositivos
  • Android AlarmManager setRepeating no se repite con un intervalo largo
  • Administrador de alarmas de Android trabajando, pero con retraso
  • ¿Cómo guardar la alarma programada después de que la aplicación fue asesinada por Android o asesino de tareas?
  • ¿Cómo configurar más de una alarma a la vez en android?
  • Administrador de alarmas en android
  • AlarmManager borrar todos los horarios en el apagado?
  • ¿Cuál es la definición de dormido para un dispositivo Android?
  • Android alarmManager setRepetición no desencadenar
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.