usando tutorial studio manager example ejemplo cancel alarma android alarmmanager

android - studio - tutorial alarmmanager



¿Cómo comprobar si AlarmManager ya tiene un conjunto de alarmas? (10)

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

Cuando se inicie mi aplicación, quiero que compruebe si una alarma en particular (registrada a través de AlarmManager) ya está configurada y en ejecución. Los resultados de google parecen indicar que no hay manera de hacer esto. ¿Esto sigue siendo correcto? Necesito hacer esta verificación para avisar al usuario antes de tomar cualquier acción para crear una nueva 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 que crea más tarde (proceso) vuelve a recuperar el mismo tipo de PendingIntent (la misma operación , el mismo Intent: acción, datos, categorías, componentes, indicadores ), recibirá un PendingIntent que representa el mismo token si aún es válido, y Por lo tanto, puede llamar a cancel () para eliminarlo.

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


Hice un sencillo script bash (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;)

intentalo ;)


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

Usar la adb shell dumpsys alarm

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


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

Puede aprender más sobre AlarmManager y su funcionamiento here . Pero aquí está la respuesta rápida.

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

Siempre tome nota de dos cosas mientras crea 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á programada o para cancelarla, solo necesita obtener acceso 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 ya. Si ya existe, devuelve la referencia al PendingIntent existente PendingIntent


Siguiendo el comentario que Ron publicó, aquí está la solución detallada. Digamos que ha registrado una alarma de repetición con un intento 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 de verificar si está activa 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, tal como se describe en javadoc: if the described PendingIntent **does not** already exists, then simply return null (en lugar de crear uno nuevo)


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

Si ya hay una alarma programada para esta Intención (con la igualdad de dos intenciones definidas por Intent.filterEquals), esta será eliminada y reemplazada por esta.

No se moleste en preguntar si existe la alarma si está intentando decidir si desea crear una alarma o no. Solo créalo cada vez que su aplicación arranque. Reemplazará 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 existe tal alarma. Para responder a estas preguntas, considere guardar los datos pref 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, la hora en que espera que suene la alarma y el período de repetición (si configura una alarma de repetición).


Tengo 2 alarmas. Estoy usando la intención con 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 extras la intención (y la alarma) no será única. Así que 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 aquí es cómo 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);


Tengo la impresión de que no hay manera de hacer esto, aunque sería bueno.

Puedes lograr un resultado similar si tienes un Alarm_last_set_time grabado en algún lugar, y si tienes un On_boot_starter BroadcastReciever: BOOT_COMPLETED algo así.


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 es crear una intención pendiente, por lo 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 AlarmManager verifique el valor de la Intención pendiente, se mostrará verdadero porque AlarmManager actualiza la marca de Intención pendiente.

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