Android: So verwenden Sie AlarmManager

88

Ich muss nach 20 Minuten einen Codeblock auslösen AlarmManager Einstellen .

Kann mir jemand einen Beispielcode zur Verwendung eines AlarmManagerin ِ Android zeigen?

Ich habe ein paar Tage mit Code herumgespielt und es wird einfach nicht funktionieren.

Tom
quelle

Antworten:

109

"Einige Beispielcodes" sind nicht so einfach, wenn es darum geht AlarmManager .

Hier ist ein Ausschnitt, der das Setup von zeigt AlarmManager:

AlarmManager mgr=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i=new Intent(context, OnAlarmReceiver.class);
PendingIntent pi=PendingIntent.getBroadcast(context, 0, i, 0);

mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), PERIOD, pi);

In diesem Beispiel verwende ich setRepeating(). Wenn Sie einen One-Shot-Alarm wünschen, verwenden Sie einfach set(). Stellen Sie sicher, dass Sie die Zeit für den Start des Alarms in derselben Zeitbasis angeben, die Sie im Anfangsparameter für verwendet haben set(). In meinem obigen Beispiel verwende ich AlarmManager.ELAPSED_REALTIME_WAKEUP, also ist meine Zeitbasis SystemClock.elapsedRealtime().

Hier ist ein größeres Beispielprojekt, das diese Technik zeigt.

CommonsWare
quelle
2
Hallo wieder. Danke für die Antwort. Wenn ich Ihr Buch kaufe, wird dann ausführlich erklärt, wie ein Alarmmanager implementiert wird?
Tom
7
Das Advanced Android-Buch (Version 0.9) enthält ca. 9 Seiten mit AlarmManager, WakeLocks und dem Rest dieses Beispiels. Das wird sich in Version 1.0 wahrscheinlich leicht erweitern, wenn ich das in meiner obigen Antwort erwähnte Update vornehme. Wenn Sie Fragen zum Buch oder zum Beispielcode haben, besuchen Sie groups.google.com/group/cw-android und ich werde diese gerne beantworten.
CommonsWare
17
Jeder Android-Entwickler sollte Marks Bücher abonnieren :) Mindestens einmal
Bostone
1
@ MarioGalván: Sie müssen es einstellen, wenn Ihre App zum ersten Mal ausgeführt wird und beim Neustart.
CommonsWare
Ich denke, Sie sollten AlarmManager.RTC_WAKEUP verwenden, wenn Sie möchten, dass es sofort und dann jede ZEIT ausgelöst wird. In Ihrem Code wird es nach SystemClock.elapsedRealtime () und dann nach jeder PERIODE ausgelöst.
Damon Yuan
66

Es gibt einige gute Beispiele im Android-Beispielcode

. \ android-sdk \ samples \ android-10 \ ApiDemos \ src \ com \ example \ android \ apis \ app

Die zum Auschecken sind:

  • AlarmController.java
  • OneShotAlarm.java

Zunächst benötigen Sie einen Empfänger, der Ihren Alarm abhören kann, wenn er ausgelöst wird. Fügen Sie Ihrer AndroidManifest.xml-Datei Folgendes hinzu

<receiver android:name=".MyAlarmReceiver" />

Erstellen Sie dann die folgende Klasse

public class MyAlarmReceiver extends BroadcastReceiver { 
     @Override
     public void onReceive(Context context, Intent intent) {
         Toast.makeText(context, "Alarm went off", Toast.LENGTH_SHORT).show();
     }
}

Verwenden Sie dann Folgendes, um einen Alarm auszulösen (z. B. in Ihrer Hauptaktivität):

AlarmManager alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, MyAlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
Calendar time = Calendar.getInstance();
time.setTimeInMillis(System.currentTimeMillis());
time.add(Calendar.SECOND, 30);
alarmMgr.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), pendingIntent);

.


Oder, noch besser, erstellen Sie eine Klasse, die alles handhabt, und verwenden Sie sie so

Bundle bundle = new Bundle();
// add extras here..
MyAlarm alarm = new MyAlarm(this, bundle, 30);

Auf diese Weise haben Sie alles an einem Ort (vergessen Sie nicht, die zu bearbeiten AndroidManifest.xml)

public class MyAlarm extends BroadcastReceiver {
    private final String REMINDER_BUNDLE = "MyReminderBundle"; 

    // this constructor is called by the alarm manager.
    public MyAlarm(){ }

    // you can use this constructor to create the alarm. 
    //  Just pass in the main activity as the context, 
    //  any extras you'd like to get later when triggered 
    //  and the timeout
     public MyAlarm(Context context, Bundle extras, int timeoutInSeconds){
         AlarmManager alarmMgr = 
             (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
         Intent intent = new Intent(context, MyAlarm.class);
         intent.putExtra(REMINDER_BUNDLE, extras);
         PendingIntent pendingIntent =
             PendingIntent.getBroadcast(context, 0, intent, 
             PendingIntent.FLAG_UPDATE_CURRENT);
         Calendar time = Calendar.getInstance();
         time.setTimeInMillis(System.currentTimeMillis());
         time.add(Calendar.SECOND, timeoutInSeconds);
         alarmMgr.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(),
                      pendingIntent);
     }

      @Override
     public void onReceive(Context context, Intent intent) {
         // here you can get the extras you passed in when creating the alarm
         //intent.getBundleExtra(REMINDER_BUNDLE));

         Toast.makeText(context, "Alarm went off", Toast.LENGTH_SHORT).show();
     }
}
Standard
quelle
2
Hallo! Ich habe diesen Code getestet und er funktioniert gut (+1). Aber ich habe dies für mehrere Alarme versucht (wie einen für 10 Sekunden und einen für 15 Sekunden, und nur der zweite wird ausgelöst. Mache ich etwas falsch oder ist es ein König des Problems? BEARBEITEN: Ok, ich habe das Problem hier gefunden : stackoverflow.com/questions/2844274/…
Nuno Gonçalves
FWIW, ich würde dafür eher eine statische Methode als einen Konstruktor verwenden.
Edward Falk
9

Was Sie tun müssen, ist zuerst die Absicht zu erstellen, die Sie planen müssen. Erhalten Sie dann den anstehenden Inhalt dieser Absicht. Sie können Aktivitäten, Dienste und Sendungen planen. So planen Sie eine Aktivität, z. B. MyActivity:

  Intent i = new Intent(getApplicationContext(), MyActivity.class);
  PendingIntent pi = PendingIntent.getActivity(getApplicationContext(),3333,i,
  PendingIntent.FLAG_CANCEL_CURRENT);

Geben Sie alarmManager diesen ausstehenden Inhalt:

  //getting current time and add 5 seconds in it
  Calendar cal = Calendar.getInstance();
  cal.add(Calendar.SECOND, 5);
  //registering our pending intent with alarmmanager
  AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
  am.set(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(), pi);

Jetzt wird MyActivity nach 5 Sekunden nach dem Start der Anwendung gestartet, unabhängig davon , ob Sie Ihre Anwendung oder Ihr Gerät in den Ruhezustand versetzt haben (aufgrund der Option RTC_WAKEUP). Sie können den vollständigen Beispielcode lesen. Planen von Aktivitäten, Diensten und Broadcasts #Android

SohailAziz
quelle
+1 tolle Antwort, genau das, was ich brauchte, ein funktionierendes Beispiel.
A. Alqadomi
4

Ich wollte aber <50 Wiederholungen kommentieren, also geht es los. Freundliche Erinnerung: Wenn Sie mit 5.1 oder höher arbeiten und ein Intervall von weniger als einer Minute verwenden, geschieht Folgendes:

Suspiciously short interval 5000 millis; expanding to 60 seconds

Siehe hier .

kurt
quelle
3

Einige Beispielcodes, wenn Sie einen Dienst vom Alarmmanager aus aufrufen möchten:

PendingIntent pi;
AlarmManager mgr;
mgr = (AlarmManager)ctx.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(DataCollectionActivity.this, HUJIDataCollectionService.class);    
pi = PendingIntent.getService(DataCollectionActivity.this, 0, i, 0);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() , 1000, pi);

Sie müssen nicht nach Benutzerberechtigungen fragen.

Das digitale Ad Venture
quelle
Eine sehr gebräuchliche Abkürzung.
Phantômaxx
0

Ein AlarmManager wird verwendet, um zu einem bestimmten Zeitpunkt Code auszulösen.

Um einen Alarm Manager zu starten, müssen Sie zuerst die Instanz vom System abrufen. Übergeben Sie dann den PendingIntent, der zu einem von Ihnen angegebenen zukünftigen Zeitpunkt ausgeführt wird

AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

Intent alarmIntent = new Intent(context, MyAlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, 0);
int interval = 8000; //repeat interval
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);

Sie müssen vorsichtig sein, wenn Sie den Alarm Manager verwenden. Normalerweise kann ein Alarmmanager nicht vor einer Minute wiederholen. Auch im Energiesparmodus kann die Dauer auf bis zu 15 Minuten erhöht werden.

Faxriddin Abdullayev
quelle