Wie überprüft man, ob AlarmManager bereits einen Alarm hat?


182

Wenn meine App startet, möchte ich überprüfen, ob ein bestimmter Alarm (registriert über AlarmManager) bereits eingestellt ist und ausgeführt wird. Die Ergebnisse von Google scheinen darauf hinzuweisen, dass dies nicht möglich ist. Ist das immer noch richtig? Ich muss diese Überprüfung durchführen, um den Benutzer zu informieren, bevor Maßnahmen zum Erstellen eines neuen Alarms ergriffen werden.

  0

Bitte bestätigen Sie die Antwort zu arbeiten, die Ihr Problem gelöst oder eine eigene Lösung erstellen. 16 jan. 172017-01-16 22:13:53

-3

Sprechen Sie der Wecker - die Quelle, die Sie hier herunterladen können - https://android.googlesource.com/platform/packages/apps/AlarmClock

Oder Sie sprechen von Abbindezeit, wenn bestimmte Aufgabe ausgeführt werden muss - http://developer.android.com/reference/android/app/AlarmManager.html

  0

haben sie es in DeskClock umbenannt: http://android.git.kernel.org/?p=platform/packages/apps/DeskClock.git;a=summary 29 dez. 102010-12-29 18:41:20

  0

Ich beziehe mich auf einen Alarm in meinem Code mit AlarmManager. Ich kann keine Methode finden, um zu überprüfen, ob für eine bestimmte Absicht bereits ein Alarm eingestellt ist. Da das Programm dem Benutzer erlaubt, einen Alarm zu setzen und dann die App zu schließen, möchte ich wissen, wenn die App geöffnet wird, ob ein Alarm eingestellt ist und "außer Sichtweite" läuft. 29 dez. 102010-12-29 19:41:19

  0

Es scheint, dass die AlarmManager-Klasse keine solche Funktionalität bietet. Hier können Sie sich die Quelle des AlarmManagers anschauen - http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.1_r2/android/app/AlarmManager.java Wenn Sie wirklich verzweifelt sind, können Sie es erweitern (oder IAlarmManager erneut implementieren) und Ihren eigenen Alarmmanager erstellen. Overkill. 29 dez. 102010-12-29 20:18:28

  0

Update: Ich entdeckte von einem anderen Thread, dass der folgende Job scheint zu tun: - 30 dez. 102010-12-30 13:27:22

+6

Alarme = (AlarmManager) getSystemService (Context.ALARM_SERVICE); \t String ALARM_ACTION; ALARM_ACTION = AAAlarmReceiver.ACTION_LOAD_LISTVIEW; Absicht intentToFire = neue Absicht (ALARM_ACTION); boolean alarmUp = (PendingIntent.getBroadcast (cText, 0, intentToFire, PendingIntent.FLAG_NO_CREATE)! = Null); 30 dez. 102010-12-30 13:27:40

  0

Bitte beantworten Sie nur die spezifische Frage in Ihrer Antwort. Wenn Sie eine Frage oder etwas anderes stellen möchten, behalten Sie es im Kommentar. 01 dez. 172017-12-01 10:39:08

  0

@RahatZaman Worüber sprichst du? Eine der Hauptüberlaufphilosophien lautet: Gib einem Mann einen Fisch und füttere ihn für einen Tag. Lehre einen Mann zum Fischen und ernähre ihn ein Leben lang. Also ist es ziemlich üblich, hier auf die Quelle der Lib hinzuweisen. 05 dez. 172017-12-05 10:06:25


1

Im unter dem Eindruck, dass Theres keine Möglichkeit, dies zu tun, wäre es aber nett.

Sie können ein ähnliches Ergebnis erreichen, indem Sie eine Alarm_last_set_time irgendwo aufgezeichnet haben und ein On_boot_starter BroadcastReciever: BOOT_COMPLETED haben.


277

Im Anschluss an den Kommentar ron, hier ist die detaillierte Lösung. Angenommen, Sie haben eine sich wiederholende Alarm mit einer anstehenden Absicht wie diese registriert haben:

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

Die Art und Weise Sie überprüfen würde, ob es aktiv ist, ist:

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

Der Schlüssel hier ist die FLAG_NO_CREATE die wie in der Javadoc beschrieben: if the described PendingIntent **does not** already exists, then simply return null (anstatt eine neue zu erstellen)

+8

Muss es den Intent nur mit einem Action String verwenden? Ich habe versucht, eine Klasse, neue Absicht (Kontext, MyClass.class) anzugeben, aber es scheint nicht zu funktionieren. Es gibt immer null zurück, auch wenn der Alarm läuft. 04 apr. 122012-04-04 08:39:49

+5

toc777, nein, es muss ein String sein, der einer deklarierten Aktion in Ihrem Intent-Filter in Ihrem Manifest entspricht.xml 11 apr. 122012-04-11 08:27:24

+4

Chris, Es war ein anderes Problem, das mein Problem verursachte. Die Absicht, die ich oben erwähnt habe, funktioniert tatsächlich :) 12 apr. 122012-04-12 12:25:50

  0

Ein Problem, das ich hatte, war nicht abbrechen auf BEIDE AlarmManager und die pendingIntent. I.E ~ alarmMgr.cancel (alarmIntent); alarmIntent.cancel(); 29 mai. 142014-05-29 12:01:21

  0

@ChrisKnight: Funktioniert das immer noch, wenn ich von einer App aus sage app1, wenn ein Alarm eingestellt ist und in App2 läuft? Und sterben die Alarme während einer App-Aktualisierung, und müssen wir sie erneut zurücksetzen (für den Anwendungsaktualisierungsfall)? 08 jul. 142014-07-08 03:25:46

+1

Gibt immer TRUE zurück und besagt, dass die ausstehende Absicht bereits vorhanden ist. Auch nach der App deinstallieren und neu installieren. Wie lange lebt die ausstehende Absicht? 13 aug. 142014-08-13 20:33:24

+30

Beachten Sie, dass Sie '' '' alarmManager.cancel (pendingIntent) '' 'und' '' pendingIntent.cancel() '' 'aufrufen müssen, damit diese Lösung false zurückgibt. 29 sep. 142014-09-29 20:00:44

+1

für Benutzer, die neue Intent verwenden (Kontext, YourService.class), können Sie .setAction ("ACTIONNAME") verwenden, um eine Aktion für die Absicht 28 nov. 142014-11-28 20:11:13

+1

Lifesaver zu definieren. Beachten Sie, dass Sie die Absicht genau so erstellen müssen, wie Sie sie zuvor erstellt haben, mit Ausnahme der Flags. 26 feb. 152015-02-26 10:07:31

+22

Wenn es nicht offensichtlich ist, überprüft der Code in dieser Antwort nicht, dass die ausstehende Absicht mit dem Alarmmanager registriert wurde. Der Code überprüft einfach, dass der PendingIntent über getBroadcast mit einer äquivalenten Zielvorgabe erstellt wurde. Sie können dies beweisen, indem Sie den alarmUp-Code nach dem getBroadcast-Befehl ausführen, aber vor allem die Kalender- und Alarmmanager-Einträge. Es wird wahr zurückkommen. Diese Tatsache erklärt, warum PendingIntent.cancel erforderlich ist, damit der Wert auf false zurückgesetzt wird. Streng genommen beantwortet dies die Frage nicht. 21 apr. 152015-04-21 21:09:49

+1

Entschuldigung. Ich möchte fragen, was ist MY_UNIQUE_ACTION? Woher kommt es? 23 jul. 152015-07-23 01:14:26

+1

@LeonardFebrianto Ich denke, es war eine lange überfällige Antwort, aber ich bin mir ziemlich sicher, dass Sie den Grund haben. Das ist nur der Aktionsname, es kann jede Aktionskonstante sein, die Sie mit Empfängern in Ihrem Manifest verknüpft haben. 15 dez. 152015-12-15 05:49:51

  0

funktioniert nicht, wenn der Alarm durch 'force stop' usw. abgebrochen wird. Vor der Verwendung dieses Codes muss 17 dez. 152015-12-17 13:55:17

+1

ausprobiert werden Intent intent = new Absicht (ctx, MyReceiver.class); anstatt unique_action zu übergeben und es hat funktioniert :) 22 dez. 152015-12-22 11:24:16

  0

ohh es arbeitet dank! 23 dez. 152015-12-23 03:46:33

+1

Tipp für zukünftige Leser - Stellen Sie sicher, dass PendingIntent.getBroadcast (...) nicht mit PendingIntent.getService (...) verwechselt wird - sparen Sie sich Ärger! :) 18 apr. 162016-04-18 04:33:00

+2

Dies ist das erste Mal, dass ich so hoch bewertete falsche Antwort. Siehe Kommentar von bigh_29. 03 jan. 172017-01-03 20:29:37


7

Ich habe 2 Alarme. Ich bin mit Absicht mit Extras statt Aktion, um die Ereignisse zu identifizieren:

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

die Sache ist, dass mit diff Extras die Absicht (und der Alarm) werden nicht eindeutig sein. So in der Lage zu erkennen, welchen Alarm aktiv ist oder nicht, ich hatte diff requestCode es zu definieren:

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

und hier ist, wie Alarm erstellt wurde:

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

Verwenden Sie die Absicht Extras und diese Lösung hat für mich funktioniert. Nur eine Änderung ist, dass ich Dienst benutze, also habe ich es geändert in 'PendingIntent.getService' 27 aug. 162016-08-27 10:07:25


92

Für andere, die diese benötigen, Hier ist eine Antwort.

Verwenden adb shell dumpsys alarm

Sie der Alarm wissen können eingestellt worden ist, und wenn sie gehen alarmiert und Intervall sind. Auch wie oft dieser Alarm ausgelöst wurde.

+4

das sollte die richtige Antwort sein 04 okt. 142014-10-04 22:07:13

+1

Das ist genau 09 dez. 142014-12-09 12:43:14

+24

Nicht wirklich eine programmatische Antwort auf das OP, aber ein cooler Tipp. Sehr gut zu wissen. 06 mai. 152015-05-06 17:38:12

+1

Anfügen eines Grep, um die normalerweise lange Liste von Alarmen zu filtern: 'adb shell dumpsys alarm | grep <z.B. Paketname Ihrer App> 'Funktioniert auch auf neuen Windows Systemen (ich benutze Win10) 08 aug. 162016-08-08 10:51:30

+2

grep wird auf dem mobilen Gerät ausgeführt, nicht auf Ihrem PC. Also, ob Grep funktioniert, hängt vom Android OS ab. Ältere Handys kommen nicht mit Grep. 07 mär. 172017-03-07 13:15:26


36

Arbeitsbeispiel mit Empfänger (die oberste Antwort war nur mit Aktion).

//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..."); 

Ich habe auch beschrieben auf meinem blog

+1

Ich bin mir nicht sicher, ob das ausreicht. Wenn ein PendingIntent beim AlarmManager registriert ist und dann von beiden Abbruchmethoden gestoppt wird, ist "isWorking" weiter gültig. Der PendingIntent wurde anscheinend nicht aus dem AlarmManager entfernt und gibt eine Instanz zurück. Wie können wir dann effektiv wissen, wann Alarme ein-/ausgeschaltet wurden? 10 jun. 162016-06-10 07:36:29

  0

Das hat wirklich perfekt funktioniert. Was zu beachten ist: setAction() und requestCode() müssen in allen getBroadcast() identisch sein und es lohnt sich, die App von Ihrem Gerät zu entfernen. Das hat mich erwischt. Danke 11 jun. 162016-06-11 10:12:42

  0

Funktioniert gut. Vielen Dank! 01 sep. 162016-09-01 12:59:48

  0

Schönes Beispiel, aber ich würde nicht 1001 als private Anfrage Code dort verwenden. Nur 0, um das Beispiel deutlicher zu machen. 09 jul. 172017-07-09 08:12:57


29

Hinweis dieses Zitat von der Dokumentation für den Alarmmanager:

Wenn es geplant bereits ein Alarm für diese Absicht ist (mit den Gleichheit von zwei Absichten wird durch Intent.filterEquals definiert, dann wird es entfernt und durch dieses ersetzt.

Fragen Sie nicht, ob der Alarm vorhanden ist, wenn Sie entscheiden möchten, ob Sie einen Alarm erstellen möchten oder nicht. Erstelle es einfach jedes Mal, wenn deine App startet. Sie werden alle von Ihnen konfigurierten vergangenen Alarme ersetzen.

Sie benötigen einen anderen Ansatz, wenn Sie versuchen zu berechnen, wie viel Zeit bei einem zuvor erstellten Alarm verbleibt oder ob Sie wirklich wissen müssen, ob ein solcher Alarm überhaupt existiert. Um diese Fragen zu beantworten, sollten Sie freigegebene Voreinstellungen zum Zeitpunkt der Erstellung des Alarms speichern. Sie könnten den Uhrzeitstempel zum Zeitpunkt des Alarms speichern, die Zeit, zu der Sie den Alarm erwarten, und den Wiederholungszeitraum (wenn Sie einen Wiederholungsalarm einrichten).

  0

Meiner Meinung nach sollte dies die akzeptierte Antwort sein. Es sei denn, das OP hat eine spezielle Situation, die es rechtfertigt, den Alarm nicht zu wiederholen. 19 mai. 162016-05-19 16:11:12

  0

In meinem Fall möchte ich wissen, ob der Alarm bereits eingestellt ist und wenn dies der Fall ist, möchte ich keinen neuen Alarm anlegen oder zurücksetzen. 21 jul. 172017-07-21 14:00:12


3

Ich habe ein einfaches (dumm oder nicht) Bash-Skript erstellt, das die Longs aus der AdB-Shell extrahiert, sie in Zeitstempel umwandelt und in Rot anzeigt.

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

versuchen Sie es;)


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 aussteht Absicht nicht schaffen, so dass es boolean Wert false gibt.

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

Nachdem der Alarmmanager den Wert Pending Intent überprüfen gibt es, weil Alarmmanager-Update Die Flagge von Schwebende Intent wahr.

  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

fand gerade eine andere Lösung, scheint es für mich

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

Manchmal wird auf Marshmallow nach dem Erzwingen der Stopp-Funktion für eine Anwendung getBroadcast() nicht null zurückgeben, aber der Alarm wird nicht gesetzt. 15 feb. 182018-02-15 20:14:10