¿Cómo verificar si el AlarmManager ya tiene un conjunto de alarmas?


182

Cuando se inicia mi aplicación, quiero que compruebe si una alarma en particular (registrada a través de AlarmManager) ya está configurada y ejecutándose. Los resultados de google parecen indicar que no hay forma de hacer esto. ¿Esto sigue siendo correcto? Necesito hacer esta comprobación para avisar al usuario antes de que se tomen medidas para crear una nueva alarma.

  0

Por favor validar la respuesta que resuelve su problema o enviar su propia solución. 16 ene. 172017-01-16 22:13:53

-3

¿Estás hablando de la alarma del reloj - la fuente se puede descargar desde aquí - https://android.googlesource.com/platform/packages/apps/AlarmClock

O usted está hablando de ajuste de la hora, cuando determinada tarea debe ser ejecutada - http://developer.android.com/reference/android/app/AlarmManager.html

  0

lo renombraron a DeskClock: http://android.git.kernel.org/?p=platform/packages/apps/DeskClock.git;a=summary 29 dic. 102010-12-29 18:41:20

  0

Me refiero a un conjunto de alarmas en mi código usando AlarmManager. No puedo encontrar ningún método para verificar si una alarma ya está configurada para un propósito particular. Como el programa permite al usuario configurar una alarma y luego cerrar la aplicación que quiero saber cuando se abre la aplicación, ya sea que se configure una alarma y se ejecute "fuera de la vista". 29 dic. 102010-12-29 19:41:19

  0

Parece que la clase AlarmManager no proporciona tal funcionalidad. Aquí puede echar un vistazo a la fuente de AlarmManager - http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.1_r2/android/app/AlarmManager.java Si está realmente desesperado, puede ampliarlo (o volver a implementar IAlarmManager) y crear su propio administrador de alarmas. Overkill. 29 dic. 102010-12-29 20:18:28

  0

Actualización: Descubrí de otro hilo que lo siguiente parece hacer el trabajo: - 30 dic. 102010-12-30 13:27:22

+6

alarms = (AlarmManager) getSystemService (Context.ALARM_SERVICE); \t Cadena ALARM_ACTION; ALARM_ACTION = AAAlarmReceiver.ACTION_LOAD_LISTVIEW; Intent intentToFire = new Intent (ALARM_ACTION); boolean alarmUp = (PendingIntent.getBroadcast (cText, 0, intentToFire, PendingIntent.FLAG_NO_CREATE)! = Null); 30 dic. 102010-12-30 13:27:40

  0

Por favor, solo responda el específico en su respuesta. Si desea hacer una pregunta o cualquier otra cosa, guárdela en el comentario. 01 dic. 172017-12-01 10:39:08

  0

@RahatZaman ¿De qué estás hablando? Una de las principales filosofías de desbordamiento de pila es "Dale a un hombre un pescado y lo alimentas por un día". Enseña a un hombre a pescar y lo alimentarás toda la vida '. Por lo tanto, señalar la fuente de la lib es una práctica muy común aquí. 05 dic. 172017-12-05 10:06:25


1

Im bajo la impresión de que los theres no hay manera de hacer esto, sería bueno sin embargo.

Puede lograr un resultado similar al grabar un Alarm_last_set_time en algún lugar, y tener un BroadcastReciever On_boot_starter: BOOT_COMPLETED algo.


277

Siguiendo con el comentario publicado ron, aquí está la solución detallada. Digamos que se haya registrado una alarma que se repite con una intención a la espera de la siguiente manera:

Intent intent = new Intent("com.my.package.MY_UNIQUE_ACTION"); 
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, 
             intent, PendingIntent.FLAG_UPDATE_CURRENT); 
Calendar calendar = Calendar.getInstance(); 
calendar.setTimeInMillis(System.currentTimeMillis()); 
calendar.add(Calendar.MINUTE, 1); 

AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60, pendingIntent); 

La forma en que le comprueba para ver si está activo es:

boolean alarmUp = (PendingIntent.getBroadcast(context, 0, 
     new Intent("com.my.package.MY_UNIQUE_ACTION"), 
     PendingIntent.FLAG_NO_CREATE) != null); 

if (alarmUp) 
{ 
    Log.d("myTag", "Alarm is already active"); 
} 

La clave aquí es la FLAG_NO_CREATE cuales como se describe en javadoc: if the described PendingIntent **does not** already exists, then simply return null (en lugar de crear uno nuevo)

+8

¿Tiene que usar la intención con solo una cadena de acción? Intenté especificar una clase, un nuevo Intento (contexto, MyClass.class) pero parece que no funciona. Siempre devuelve nulo incluso cuando la alarma se está ejecutando. 04 abr. 122012-04-04 08:39:49

+5

toc777, no necesita ser una cadena que coincida con una acción declarada en su filtro de intención en su manifiesto.xml 11 abr. 122012-04-11 08:27:24

+4

Chris, era otro problema que causaba mi problema. La intención que mencioné anteriormente realmente funciona :) 12 abr. 122012-04-12 12:25:50

  0

Un problema que tuve no fue cancelar tanto en el AlarmManager como en el pendingIntent. I.E ~ alarmMgr.cancel (alarmIntent); alarmIntent.cancel(); 29 may. 142014-05-29 12:01:21

  0

@ChrisKnight: ¿Esto funcionará si reviso desde una aplicación, por ejemplo, app1 si hay una alarma configurada y ejecutándose en la aplicación2? y también, ¿las alarmas mueren durante una actualización de la aplicación, y entonces necesitamos reiniciarlo de nuevo (para el caso de actualización de la aplicación)? 08 jul. 142014-07-08 03:25:46

+1

Siempre devuelve VERDADERO diciendo que el intento pendiente ya existe. Incluso después de la desinstalación y reinstalación de la aplicación. ¿Cuánto tiempo dura el intento pendiente? 13 ago. 142014-08-13 20:33:24

+30

Tenga en cuenta que tendrá que llamar a '' 'alarmManager.cancel (pendingIntent)' '' y '' 'pendingIntent.cancel()' '' para que esta solución devuelva false. 29 sep. 142014-09-29 20:00:44

+1

para los usuarios que usen nueva intención (contexto, YourService.class), puede usar .setAction ("ACTIONNAME") para definir una acción en la intención 28 nov. 142014-11-28 20:11:13

+1

Lifesaver. Tenga en cuenta que deberá crear la intención exactamente de la misma manera que la creó antes, a excepción de las banderas. 26 feb. 152015-02-26 10:07:31

+22

En caso de que no sea obvio, el código en esta respuesta no verifica que el intento pendiente haya sido registrado con el administrador de alarmas. El código simplemente verifica que el PendingIntent se haya creado a través de getBroadcast con una intención de objetivo equivalente. Puedes probar esto ejecutando el código de alarmUp después del getBroadcast todo, pero antes de todo el calendario y el administrador de alarmas. Volverá verdadero. Este hecho explica por qué tiene que PendingIntent.cancel para obtener el valor para volver a falso. Estrictamente hablando, esto no responde la pregunta. 21 abr. 152015-04-21 21:09:49

+1

Disculpe. Quiero preguntar ¿cuál es MY_UNIQUE_ACTION? ¿De dónde viene? 23 jul. 152015-07-23 01:14:26

+1

@LeonardFebrianto, creo que fue una respuesta largamente esperada, pero estoy bastante seguro de que tienes el motivo. Eso es solo el nombre de la acción, puede ser cualquier constante de acción que haya asociado con los receptores en su manifiesto 15 dic. 152015-12-15 05:49:51

  0

no funciona si la alarma ha sido anulada por 'force stop', etc. Debe ser cancelada antes de usar este código 17 dic. 152015-12-17 13:55:17

+1

He intentado intento = nuevo Intención (ctx, MyReceiver.class); en lugar de pasar unique_action y funcionó :) 22 dic. 152015-12-22 11:24:16

  0

ohh está funcionando gracias! 23 dic. 152015-12-23 03:46:33

+1

consejo para futuros lectores: asegúrese de no confundir PendingIntent.getBroadcast (...) con PendingIntent.getService (...) - ahórrese algunos problemas. :) 18 abr. 162016-04-18 04:33:00

+2

esta es la primera vez que veo una respuesta INCORRECTA tan alta. Ver el comentario de bigh_29. 03 ene. 172017-01-03 20:29:37


7

Tengo 2 alarmas. Estoy utilizando la intención de extras en lugar de acción para identificar los eventos:

Intent i = new Intent(context, AppReciever.class); 
i.putExtra("timer", "timer1"); 

la cosa es que con extras diff la intención (y la alarma) no será única. Así que para poder identificar qué alarma está activa o no, tuviera que definir diff requestCode -s:

boolean alarmUp = (PendingIntent.getBroadcast(context, MyApp.TIMER_1, i, 
        PendingIntent.FLAG_NO_CREATE) != null); 

y aquí es cómo se creó alarma:

public static final int TIMER_1 = 1; 
public static final int TIMER_2 = 2; 

PendingIntent pending = PendingIntent.getBroadcast(context, TIMER_1, i, 
      PendingIntent.FLAG_CANCEL_CURRENT); 
setInexactRepeating(AlarmManager.RTC_WAKEUP, 
      cal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pending); 
pending = PendingIntent.getBroadcast(context, TIMER_2, i, 
      PendingIntent.FLAG_CANCEL_CURRENT); 
setInexactRepeating(AlarmManager.RTC_WAKEUP, 
      cal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pending); 
  0

Usando los extras de intención y esta solución funcionó para mí. Solo un cambio es que estoy usando el servicio, así que lo cambié a 'PendingIntent.getService' 27 ago. 162016-08-27 10:07:25


92

Para otros que puedan necesitar esto, aquí hay una respuesta.

Uso adb shell dumpsys alarm

Usted puede saber que la alarma se ha ajustado y cuándo se va a alarmado e intervalo. También cuántas veces se ha invocado esta alarma.

+4

esta debería ser la respuesta correcta 04 oct. 142014-10-04 22:07:13

+1

Esto es exactamente 09 dic. 142014-12-09 12:43:14

+24

No es realmente una respuesta programática al OP, pero es una buena sugerencia. Muy bueno saber 06 may. 152015-05-06 17:38:12

+1

anexe un grep para filtrar la larga lista de alarmas: 'adb shell dumpsys alarm | grep <e.g. nombre del paquete de su aplicación> 'También funciona en los nuevos sistemas de Windows (yo uso Win10) 08 ago. 162016-08-08 10:51:30

+2

grep se ejecuta en el dispositivo móvil, no en su PC. Entonces, si grep funciona, depende del sistema operativo Android. Los teléfonos viejos no vienen con grep. 07 mar. 172017-03-07 13:15:26


36

Ejemplo de trabajo con receptor (la respuesta principal fue solo con la acción).

//starting 
AlarmManager alarmManager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE); 
Intent intent = new Intent(getActivity(), MyReceiver.class); 
intent.setAction(MyReceiver.ACTION_ALARM_RECEIVER);//my custom string action name 
PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity(), 1001, intent, PendingIntent.FLAG_CANCEL_CURRENT);//used unique ID as 1001 
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), aroundInterval, pendingIntent);//first start will start asap 

//and stopping 
Intent intent = new Intent(getActivity(), MyReceiver.class);//the same as up 
intent.setAction(MyReceiver.ACTION_ALARM_RECEIVER);//the same as up 
PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity(), 1001, intent, PendingIntent.FLAG_CANCEL_CURRENT);//the same as up 
alarmManager.cancel(pendingIntent);//important 
pendingIntent.cancel();//important 

//checking if alram is working with pendingIntent 
Intent intent = new Intent(getActivity(), MyReceiver.class);//the same as up 
intent.setAction(MyReceiver.ACTION_ALARM_RECEIVER);//the same as up 
boolean isWorking = (PendingIntent.getBroadcast(getActivity(), 1001, intent, PendingIntent.FLAG_NO_CREATE) != null);//just changed the flag 
Log.d(TAG, "alarm is " + (isWorking ? "" : "not") + " working..."); 

que he descrito también en mi blog

+1

No estoy seguro de que esto sea suficiente. En el caso en que PendingIntent esté registrado con el AlarmManager y luego sea detenido por ambos métodos de cancelación, 'isWorking' anterior seguirá siendo verdadero. El PendingIntent parece que no se ha eliminado del AlarmManager y seguirá devolviendo una instancia. ¿Cómo podemos saber efectivamente cuándo se activaron/desactivaron las alarmas? 10 jun. 162016-06-10 07:36:29

  0

Esto realmente funcionó perfectamente. Aspectos a tener en cuenta: el setAction() y el requestCode() deben ser idénticos en todos los getBroadcast() y vale la pena desinstalar la aplicación de su dispositivo. Eso me sorprendió Gracias 11 jun. 162016-06-11 10:12:42

  0

Funciona muy bien. ¡Gracias! 01 sep. 162016-09-01 12:59:48

  0

Buen ejemplo, pero no usaría 1001 como código de solicitud privado allí. Solo 0 para que el ejemplo sea más obvio. 09 jul. 172017-07-09 08:12:57


29

Nota esta cita de la documentación para el gestor de alarma:

Si ya hay una alarma programada para este fin (con la igualdad de dos intenciones definidas por Intent.filterEquals), entonces se eliminará y se reemplazará por esta.

No se moleste en preguntar si la alarma existe si está tratando de decidir si crear una alarma o no. Solo créelo cada vez que se inicie su aplicación. Reemplazará todas las alarmas pasadas que haya configurado.

Necesita un enfoque diferente si está tratando de calcular cuánto tiempo le queda a una alarma creada anteriormente, o si realmente necesita saber si dicha alarma existe. Para responder esas preguntas, considere guardar los datos prefidos compartidos en el momento de crear la alarma. Puede almacenar la marca de tiempo del reloj en el momento en que se configuró la alarma, el tiempo que espera que suene la alarma y el período de repetición (si configura una alarma que se repite).

  0

En mi opinión, esta debería ser la respuesta aceptada. A menos que el OP tenga una situación especial que justifique que no se repita la alarma 19 may. 162016-05-19 16:11:12

  0

En mi caso, quiero saber si la alarma ya está configurada y, de ser así, no quiero crear una nueva o restablecer la alarma existente. 21 jul. 172017-07-21 14:00:12


3

Hice un script bash simple (estúpido o no), que extrae los largos del shell adb, los convierte en marcas de tiempo y los muestra en rojo.

echo "Please set a search filter" 
read search 

adb shell dumpsys alarm | grep $search | (while read i; do echo $i; _DT=$(echo $i | grep -Eo 'when\s+([0-9]{10})' | tr -d '[[:alpha:][:space:]]'); if [ $_DT ]; then echo -e "\e[31m$(date -d @$_DT)\e[0m"; fi; done;) 

probarlo;)


2
Intent intent = new Intent("com.my.package.MY_UNIQUE_ACTION"); 
      PendingIntent pendingIntent = PendingIntent.getBroadcast(
        sqlitewraper.context, 0, intent, 
        PendingIntent.FLAG_NO_CREATE); 

FLAG_NO_CREATE no se crean intención pendiente de lo que le da valor booleano falso.

  boolean alarmUp = (PendingIntent.getBroadcast(sqlitewraper.context, 0, 
        new Intent("com.my.package.MY_UNIQUE_ACTION"), 
        PendingIntent.FLAG_NO_CREATE) != null); 

      if (alarmUp) { 
       System.out.print("k"); 

      } 

      AlarmManager alarmManager = (AlarmManager) sqlitewraper.context 
        .getSystemService(Context.ALARM_SERVICE); 
      alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, 
        System.currentTimeMillis(), 1000 * 60, pendingIntent); 

Después de la AlarmManager comprobar el valor de la pendiente de Intención que da cierto porque AlarmManager actualización de la bandera de Intención En espera.

  boolean alarmUp1 = (PendingIntent.getBroadcast(sqlitewraper.context, 0, 
        new Intent("com.my.package.MY_UNIQUE_ACTION"), 
        PendingIntent.FLAG_UPDATE_CURRENT) != null); 
      if (alarmUp1) { 
       System.out.print("k"); 

      } 

5

acaba de encontrar otra solución, que parece que funciona para mí

Intent myIntent = new Intent(MainActivity.this, MyReceiver.class); 

boolean isWorking = (PendingIntent.getBroadcast(MainActivity.this, 0, myIntent, PendingIntent.FLAG_NO_CREATE) != null); 
if (isWorking) {Log.d("alarm", "is working");} else {Log.d("alarm", "is not working");} 

if(!isWorking) { 
    pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT); 
    alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); 
    int timeNotif = 5 * 60 * 1000;//time in ms, 7*24*60*60*1000 for 1 week 
    Log.d("Notif", "Notification every (ms): " + timeNotif); 
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), timeNotif, pendingIntent); 
    } 
  0

A veces, en Marshmallow, después de forzar y detener una aplicación, getBroadcast() devolverá no nulo, pero la alarma no está configurada. 15 feb. 182018-02-15 20:14:10