80

Potrzebuję wyzwolić blok kodu po 20 minutach od ustawienia AlarmManager.Android: Jak korzystać z AlarmManager

Czy ktoś może pokazać mi przykładowy kod na temat korzystania z urządzenia AlarmManager w systemie Android?

Przez kilka dni bawiłem się z kodem i to po prostu nie zadziała.

Odpowiedz

100

"Niektóre przykładowy kod" nie jest takie proste, jeśli chodzi o AlarmManager.

Oto fragment pokazujący konfigurację 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); 

W tym przykładzie używam setRepeating(). Jeśli potrzebujesz jednorazowego alarmu, po prostu użyjesz set(). Pamiętaj, aby dać czas na uruchomienie alarmu w tej samej bazie czasowej, co w początkowym parametrze do set(). W powyższym przykładzie używam AlarmManager.ELAPSED_REALTIME_WAKEUP, więc moja baza czasowa to SystemClock.elapsedRealtime().

Here is a larger sample project pokazano tę technikę.

+2

Witaj ponownie. Dziękuję za odpowiedź. Jeśli kupię twoją książkę, czy wyjaśnia ona, w jaki sposób można w pełni zaimplementować menedżera alarmów? – Tom

+7

Książka Advanced Android (wersja 0.9) zawiera ~ 9 stron obejmujących AlarmManager, WakeLocks i resztę tego przykładu. Prawdopodobnie ulegnie to nieznacznemu rozszerzeniu w wersji 1.0, kiedy poprawiam poprawkę, o której wspomniałem w powyższej odpowiedzi. Jeśli masz pytania dotyczące książki lub jej przykładowego kodu, przejdź do http://groups.google.com/group/cw-android, a z przyjemnością odpowiem na nie. – CommonsWare

+17

Każdy programista Android powinien mieć subskrypcję książek Marka :) Co najmniej raz – Bostone

58

Istnieją dobre przykłady w androidki przykładowego kodu

. \ Android sdk \ próbki \ Android 10 \ ApiDemos \ src \ pl \ przykład \ android \ API \ app

Te, aby sprawdzić to:

  • AlarmController.java
  • OneShotAlarm.java

Po pierwsze, potrzebujesz odbiornika, czegoś, co może wysłuchać alarmu, gdy zostanie uruchomiony. Dodaj poniższe linie do pliku AndroidManifest.xml

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

Następnie należy utworzyć następujące klasy

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

Następnie, aby wywołać alarm, użyj następujących (na przykład w swojej głównej działalności):

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

.


Albo, jeszcze lepiej, zrobić klasę, która obsługuje to wszystko i używać go jak ten

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

ten sposób, masz to wszystko w jednym miejscu (nie zapomnij, aby edytować 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(); 
    } 
} 
+1

Cześć! Przetestowałem ten kod i jest on w porządku (+1). ale próbowałem to dla wielu alarmów (jak jeden na 10 sekund, a drugi na 15, i tylko ten sencond jest zwolniony.) Czy robię coś źle, czy jest to jakiś król problemu? EDYCJA: OK, znalazłem problem tutaj: http://stackoverflow.com/questions/2844274/multiple-calls-to-alarmmanager-setrepeating-deliver-the-same-intent-pendinginten –

+1

+1 za odniesienie do próbek SDK – Sundeep

+0

FWIW, użyłbym statycznej metody raczej niż konstruktor do tego. –

2

Niektóre przykładowy kod, gdy chcesz wywołać usługę z Alarmmanager:

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

Nie musisz pytać o uprawnienia użytkownika.

+0

co to jest tutaj ctx? – ssrp

+2

ctx to kontekst :) – Duc

+0

Bardzo popularny skrót. –

7

Należy najpierw utworzyć intencję, którą należy zaplanować. Następnie uzyskaj oczekującą intencję tego zamiaru. Możesz zaplanować działania, usługi i transmisje. Aby zaplanować aktywność np MyActivity:

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

dać ten pendingIntent do alarmManager:

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

Teraz MyActivity będą uruchomiona po upływie 5 sekund od uruchomienia aplikacji, bez względu na to zatrzymać aplikację lub urządzenie przeszło w stan uśpienia (z powodu opcji RTC_WAKEUP). Możesz przeczytać pełny przykładowy kod Scheduling activities, services and broadcasts #Android

+0

+1 wspaniała odpowiedź, dokładnie to, czego potrzebowałem, działający przykład "zestaw". –

3

Chciałem skomentować, ale < 50 rep, więc tutaj idzie. Przypominamy, że jeśli działa na 5.1 lub powyżej używać w odstępie mniej niż minutę, to się dzieje:

Suspiciously short interval 5000 millis; expanding to 60 seconds 

Zobacz here.