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

Cuando se inicia mi aplicación, quiero que compruebe si una alarma 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 tome alguna medida para crear una nueva alarma.

Siguiendo con el comentario que Ron publicó, aquí está la solución detallada. Digamos que ha registrado una alarma repetitiva con un bash pendiente como este:

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 verificaría 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 FLAG_NO_CREATE que como se describe en javadoc: if the described PendingIntent **does not** already exists, then simply return null (en lugar de crear uno nuevo)

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

Utilice adb shell dumpsys alarm

Puede saber que la alarma se ha configurado y cuándo van a alarmarse e intervalo. También cuántas veces se ha invocado esta alarma.

Ejemplo de trabajo con el 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 alarm 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..."); 

Vale la pena mencionar:

Si la aplicación creadora más tarde (proceso) vuelve a recuperar el mismo tipo de PendingIntent (misma operación , mismo Intento – acción, datos, categorías, componentes, indicadores ), recibirá un PendingIntent que represente el mismo token si eso sigue siendo válido, y por lo tanto, puede llamar a cancel () para eliminarlo.

En resumen, su PendingIntent debe tener las mismas características (estructura de operación e intención) para tomar el control sobre él.

Tenga en cuenta esta cita de los documentos para el administrador de alarmas:

Si ya hay una alarma para este bash progtwigdo (con la intención de que Intent.filterEquals defina la igualdad de dos bashs), se eliminará y se reemplazará por este.

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).

Tengo 2 alarmas Estoy usando intenciones con extras en lugar de acción para identificar los eventos:

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

el problema es que con los extras de diferencia la intención (y la alarma) no serán únicas. Para poder identificar qué alarma está activa o no, tuve que definir diff requestCode -s:

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

y así es como se creó la 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); 

Acabo de encontrar otra solución, parece funcionar 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); } 

Hice un script bash simple (estúpido o no), que extrae los largos del shell adb, los convierte a marcas de tiempo y lo 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;) 

intentalo 😉

Estoy bajo la impresión de que 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 elemento BroadcastReciever: BOOT_COMPLETED de On_boot_starter.

  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 crea un bash pendiente de modo que da un 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 que el AlarmManager verifique el valor de Pending Intent, da verdadero porque AlarmManager Update The Flag of Pending Intent.

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

Si bien casi todos aquí han dado la respuesta correcta, ningún cuerpo explicó en qué se basan las alarmas

En realidad, puede obtener más información sobre AlarmManager y su funcionamiento aquí . Pero aquí está la respuesta rápida

Verás, AlarmManager básicamente progtwig un PendingIntent en algún momento en el futuro. Por lo tanto, para cancelar la alarma progtwigda, debe cancelar el PendingIntent .

Siempre tenga en cuenta dos cosas al crear el PendingIntent

 PendingIntent.getBroadcast(context,REQUEST_CODE,intent, PendingIntent.FLAG_UPDATE_CURRENT); 
  • Código de solicitud – Actúa como el identificador único
  • Bandera: define el comportamiento de PendingIntent

Ahora, para verificar si la alarma ya está progtwigda o cancelar la alarma, solo necesita acceder al mismo PendingIntent . Esto se puede hacer si usa el mismo código de solicitud y usa FLAG_NO_CREATE como se muestra a continuación

 PendingIntent pendingIntent=PendingIntent.getBroadcast(this,REQUEST_CODE,intent,PendingIntent.FLAG_NO_CREATE); if (pendingIntent!=null) alarmManager.cancel(pendingIntent); 

Con FLAG_NO_CREATE devolverá null si el PendingIntent no existe. Si ya existe, devuelve una referencia al existente PendingIntent