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
- Cancelar un AlarmManager pendienteIntent en otro pendienteintent
- Aclaración del comportamiento de AlarmManager en Android
- AlarmManager en fecha y hora específicas
- ¿Cuál es la mejor manera de crear un recordatorio de citas en Android?
- ¿Qué sucede con AlarmManager no entregado al repetir alarmas cuando el teléfono se despierta?
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.
- Cómo configurar la alarma en Android?
- ¿Cómo ejecutar una función de Android cada 15 minutos, y específicamente en la marca de 15 minutos todos los días?
- Android setRepeating () y setInexactRepeating () no se disparan
- ¿Android AlarmManager controla los cambios de horario de verano?
- Cómo programar una tarea mediante el Administrador de alarmas
- Cómo permitir que el teléfono funcione mientras usa la alarma RTC en Android
- Android AlarmManager activa cada "ronda" 10 minutos
- Android AlarmManager no despertar teléfono hasta
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.
- Error al inflar la clase de botón personalizado. NoSuchMethodException
- Diferenciación entre desplazamiento de usuario y cambio de página de programación en ViewPager