android adb alarmmanager

android - Cómo leer la salida "alarma de adb shell dumpsys"



alarmmanager (3)

Estoy luchando por configurar una alarma correctamente y por comprender el mecanismo de cancelación y reprogramación de alarmas.

He descubierto que hay un comando adb para recuperar todas las alarmas programadas en el dispositivo, pero no he encontrado una documentación que explique el formato de la salida.

Entiendo que estoy pidiendo muchas explicaciones aquí, así que si alguien arroja un enlace con una explicación detallada sobre "alarma adb shell dumpsys", realmente lo agradeceré.

Entonces, aquí están las preguntas:

  1. Lotes de alarmas pendientes: 23

    a. ¿Es ''23'' una cantidad de alarmas programadas actualmente activas?

  2. Lote {4293d3a8 num = 1 inicio = 1369361 final = 1407261}:
    RTC # 0: Alarma {4293d358 tipo 1 com.android.chrome}
    type = 1 whenElapsed = 1369361 when = + 19s304ms window = -1 repeatInterval = 0 count = 0
    operación = PendingIntent {429e4500: PendingIntentRecord {429dbbc8 com.android.chrome broadcastIntent}}

    a. ¿Qué es ''num = 1'', ''start = 1369361'' y ''end = 1407261''?
    si. ''RTC'' significa alarma RTC, supongo.
    C. ¿Qué significa ''# 0''?
    re. ¿Qué significa ''tipo = 1''?
    mi. ¿''When = + 19s304ms'' significa que la alarma se activará en 19 segundos?
    F. ¿Qué significa ''ventana = -1''?
    sol. ¿''RepeatInterval = 0'' significa que esta alarma no se repite?
    h. ¿''Count = 0'' significa que esta alarma no se pospuso debido al estado de suspensión del teléfono?
    yo. ''operación = PendingIntent {...}'' representa la intención pendiente, que se activará por alarma, supongo.

  3. Número de referencia de transmisión: 0

    a. ¿Que es esto?

  4. Alarmas superiores:

    a. ¿Que es esto?

  5. + 47s271ms en ejecución, 0 despertadores, 2 alarmas: com.username.weatherinfo
    act = com.username.receivers.CyclicWeatherUpdater.WEATHER_UPDATE_ACTION
    cmp = {com.username.weatherinfo / com.username.receivers.CyclicWeatherUpdater}

    a. ¿''+ 47s271ms'' significa que esta alarma se activará en 47 segundos?
    si. ¿Qué es ''0 despertadores''? ¿La alarma nunca se activó?
    C. ¿Qué son las ''2 alarmas''?
    re. ¿''Com.username.weatherinfo'' representa el nombre del paquete que se le dio a la intención pendiente en el campo de contexto?
    mi. ¿''Acto'' significa la acción, que fue enviada por intención?
    F. ¿Qué es ''cmp''? Ya veo, que se compone del nombre del paquete y el nombre de la clase, pero ¿de dónde se toman? ¿De la intención del constructor? sol. ¿Por qué parte de las alarmas solo tienen ''act'' o solo ''cmp''? Supuse que las alarmas sin campos ''cmp'' son para intenciones de transmisión implícitas. Sin embargo, ¿por qué hay alarmas sin el campo ''actuar''?

  6. Estadísticas de alarma:

    a. ¿Que es esto?


Aunque la respuesta morpática es todo lo que necesita saber, he creado un proyecto de código abierto para que una GUI muestre la misma información de forma visual. Creo que podría ser útil para otros, ya que lo ha sido para mí en primer lugar.

https://github.com/Dottorhouse/DumpsysAlarm


Como alguien que también luchó con las alarmas, aquí hay dos consejos:

Depuración de salida de shell:

  • ver tiempos negativos o enormes (por ejemplo, -2hr57m20s311ms, 14d5hr23m07s500ms), fue porque confundí el tipo de reloj (por ejemplo, RTC con ELAPSED). Esto está claro en la documentación, " RTC_WAKEUP: Alarm time in System.currentTimeMillis() " https://developer.android.com/reference/android/app/AlarmManager.html#RTC_WAKEUP

  • cancelar alarmas en tiempo real (después de crearlas). Use cancelar, que si programó una intención pendiente necesita tanto: alarmManager.cancel(pendingIntent) como pendingIntent.cancel()


Me doy cuenta de que este hilo es antiguo, pero las respuestas no son fáciles de encontrar y podrían ser útiles. He pasado un buen tiempo resolviendo qué significan estos mensajes.

Q1: lotes

Pending alarm batches: 23

Las alarmas se organizan en lotes. Como se describe en la documentación :

A partir de API 19, el tiempo de activación pasado a este método se trata como inexacto: la alarma no se entregará antes de este momento, pero puede diferirse y entregarse algún tiempo después. El sistema operativo utilizará esta política para " agrupar " las alarmas en todo el sistema, minimizando la cantidad de veces que el dispositivo necesita "reactivarse" y minimizando el uso de la batería. En general, las alarmas programadas en el futuro cercano no se diferirán mientras las alarmas se programen en el futuro.

Puede haber más de una alarma por lote. En este caso, hay 23 lotes de alarmas, lo que significa que probablemente hay muchas más de 23 alarmas programadas. En la salida de dumpsys alarm , la línea que describe cada lote se ve así:

Batch{4293d3a8 num=1 start=1369361 end=1407261}:

En el cual:

  • 4293d3a8 es una identificación interna asociada con el lote.
  • num=1 es el número de alarmas en este lote. En este caso, solo hay una alarma en el lote.
  • Los números de start y end representan el número de milisegundos que han transcurrido desde la última vez que se reinició el sistema como se describe en esta publicación , y también representan aproximadamente la ventana de tiempo en la que se deben activar las alarmas en el lote.

Q2: alarmas

Cada alarma se describe mediante tres líneas que se ven así:

RTC #0: Alarm{4293d358 type 1 com.android.chrome} type=1 whenElapsed=1369361 when=+19s304ms window=-1 repeatInterval=0 count=0 operation=PendingIntent{429e4500: PendingIntentRecord{429dbbc8 com.android.chrome broadcastIntent}}

En el cual:

  • La primera parte, que es una de RTC_WAKEUP , RTC , ELAPSED_WAKEUP o ELAPSED , representa el type de alarma y corresponde a un valor entero 0-3, respectivamente
  • #0 es el número de la alarma dentro del lote, donde los números van de 0 a n-1 donde n es el número de alarmas en el lote. Si su alarma se agrupa con otros, el más lejano en el futuro "cuando =" define la hora en que se activarán todas las alarmas del lote.
  • 4293d358 es un número de identificación interno asociado con la alarma
  • com.android.chrome es el nombre del paquete de la clase que activó la alarma
  • type=1 , el tipo de alarma, vea la primera viñeta arriba
  • whenElapsed=1369361 refiere al número de milisegundos desde que se inició el sistema en el que se activará esta alarma (aproximadamente)
  • when=+19s304ms significa que la alarma se activará en 19 segundos, 304 milisegundos desde el momento en que se dumpsys alarm . Del mismo modo, un valor como +2d13h29m03s882ms refiere a un tiempo relativo de 2 días, 13 horas, 29 minutos ... en el futuro
  • window= refiere a una de las dos constantes internas que tienen que ver con el método en el que se agrupa la alarma. AlarmManager.WINDOW_EXACT=0 y se establece cuando la alarma se programa con setExact() o setAlarmClock() . AlarmManager.WINDOW_HEURISTIC=-1 y se establece cuando la alarma se programa con setInexactRepeating() . De lo contrario, el valor está determinado por la versión de la API. Para API <19 (KitKat), se utiliza WINDOW_EXACT y para API> = 19, se utiliza WINDOW_HEURISTIC . (Tuve que profundizar en el código fuente de AlarmManager.java para resolver esto).
  • repeatInterval=900000 es la frecuencia con la que se repite la alarma, por ejemplo, cada 900000 ms o 15 minutos. Un valor de 0 significa que la alarma no se repite.
  • count= refiere al número de veces que una alarma debería haberse activado, pero no fue por alguna razón. 0 es un buen número aquí. > 0 significa que la alarma se omitió por alguna razón.
  • operation=PendingIntent{...} es una referencia al PendingIntent que se activa por la alarma. Dependiendo de si el PendingIntent fue instanciado usando getService , getBroadcast , getActivity o getActivities , la alarma iniciará un servicio, enviará una transmisión o comenzará una o más actividades.

P3: Recuento de referencia de transmisión

Para averiguar sobre esto y los otros elementos de salida después de esto, tuve que cavar en el código fuente de AlarmManagerService.java .

Para que algunas alarmas funcionen, el dispositivo debe ser activado y no debe volver a dormir hasta que se hayan enviado todas las transmisiones necesarias. La variable interna mBroadcastRefCount se inicializa en 0 y se incrementa a medida que las transmisiones a enviar se ponen en cola. A medida que se envía cada transmisión, disminuye y cuando vuelve a 0, se libera el wakeLock y está bien que el dispositivo vuelva a dormir.

Broadcast Ref Count: 0 simplemente significa que en el momento en que se dumpsys alarm , no estaba en el medio de enviar ninguna transmisión.

Q4: principales alarmas

Estas son las diez alarmas principales clasificadas en orden descendente por el tiempo total agregado que se ha ejecutado el código de alarma. Esto se puede utilizar para buscar alarmas que consuman la mayor cantidad de recursos del sistema, por ejemplo, para encontrar procesos que pueden tener la culpa de agotar la vida de la batería.

Q5: Estadísticas de alarma

Esta sección muestra las estadísticas de todas las alarmas que se han ejecutado desde la última vez que se reinició el sistema. Aquí es donde puede ver si las alarmas que configuró en el pasado se activaron, si despertaron el teléfono, etc. El formato de estas entradas se trata a continuación.

Q6: Entradas de estadísticas de alarma

Las entradas de estadísticas de alarma se ven así:

com.example.someapp +1s857ms running, 0 wakeups: +1s817ms 0 wakes 83 alarms: cmp={com.example.someapp/com.example.someapp.someservice} +40ms 0 wakes 1 alarms: cmp={com.example.someapp/com.example.someapp.someotherservice}

donde en la primera línea:

  • com.example.someapp es el nombre del paquete del proceso que activó la alarma
  • +1s857ms running es el tiempo total del sistema consumido por los procesos
  • 0 wakeups es la cantidad de veces que una de estas alarmas despertó el dispositivo

y luego cada línea después de eso se refiere a una de las alarmas configuradas, con:

  • +1s817ms es el tiempo total consumido del sistema
  • 0 wakes es la cantidad de veces que se tuvo que despertar el dispositivo
  • 83 alarms es el número de veces que se ha activado la alarma; esto solo será> 1 para repetir alarmas
  • cmp={...} el servicio que se inició cuando se activó la alarma

Alternativamente, si la alarma activó una transmisión, la entrada podría verse así:

android +4m51s566ms running, 281 wakeups: +2m46s583ms 0 wakes 1224 alarms: act=android.intent.action.TIME_TICK +1m25s624ms 89 wakes 89 alarms: act=android.content.syncmanager.SYNC_ALARM +52s898ms 0 wakes 41 alarms: act=com.android.server.action.NETWORK_STATS_POLL ...

con:

  • act=... siendo el nombre de la intención que se transmitió

Es posible que una alarma tenga tanto una entrada cmp={...} como una entrada act=... , lo que significa que la alarma transmitió una intención e inició un servicio.

Resumen

La depuración de alarmas de Android usando la salida de la adb shell dumpsys alarm de adb shell dumpsys alarm puede ser complicada, y no hay una ubicación central donde se expliquen completamente los mensajes dumpsys . No siempre es evidente cómo se agrupan las alarmas, y a veces es difícil lograr que un servicio o actividad se active exactamente cuando se desea. Esperemos que esta sea una referencia útil para las personas que intentan depurar sus alarmas.