2010-12-13 11 views
15

Obecnie próbuję napisać menedżera alarmów, który wyłączy alarm w określonym czasie, codziennie. Najpierw należy sprawdzić, czy użytkownik miał Ustaw alarm na tym, że na dzień:Jak ustawić cykliczny menedżer alarmów do wykonywania kodu codziennie

 if ((User.getReminderTime(Home.this) > 0) 
    && (dt.getDate() != today.getDate() || dt.getDay() != today 
     .getDay())) { 
    AppointmentManager.setFutureAppointmentCheck(this 
    .getApplicationContext()); 
    User.setLongSetting(this, "futureappts", today.getTime()); 
    } 

potem pójdę i określić rzeczywisty alarm zgaśnie między 12 a 12:10 następnego dnia:

 public static void setFutureAppointmentCheck(Context con) { 
    AlarmManager am = (AlarmManager) con 
    .getSystemService(Context.ALARM_SERVICE); 

    Date futureDate = new Date(new Date().getTime() + 86400000); 
    Random generator = new Random(); 

    futureDate.setHours(0); 
    futureDate.setMinutes(generator.nextInt(10)); 
    futureDate.setSeconds(0); 

    Intent intent = new Intent(con, FutureAppointmentReciever.class); 

    PendingIntent sender = PendingIntent.getBroadcast(con, 0, intent, 
    PendingIntent.FLAG_ONE_SHOT); 

    am.set(AlarmManager.RTC_WAKEUP, futureDate.getTime(), sender); 

} 

Teraz konfiguruję środowisko testowe, aby to się włączało co dwie minuty i wygląda na to, że działa dobrze, ale kiedy wdrażam urządzenie, urządzenie wydaje się nie odbierać alarmów. Pomyślałem, że może to być problem z uśpionym urządzeniem, więc dodałem menedżera zasilania. Ale to nadal nie działa:

 PowerManager pm = (PowerManager) context 
    .getSystemService(Context.POWER_SERVICE); 
    PowerManager.WakeLock wl = pm.newWakeLock(
    PowerManager.PARTIAL_WAKE_LOCK, "keepAlive"); 
    wl.acquire(); 
    setFutureAppointments(context.getApplicationContext()); 
    AppointmentManager.setFutureAppointmentCheck(context 
    .getApplicationContext()); 
    User.setLongSetting(context.getApplicationContext(), "futureappts", 
    new Date().getTime()); 
    wl.release(); 

ktoś widział cokolwiek robie rażąco błędne lub będę o tym niepoprawnie? dzięki za wszelką pomoc.

Odpowiedz

43

zwykle zrobić coś więcej wzdłuż linii:

Intent i = new Intent(this, MyService.class); 
PendingIntent pi = PendingIntent.getService(this, 0, i, 0); 
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE); 
am.cancel(pi); // cancel any existing alarms 
am.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 
    SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_DAY, 
    AlarmManager.INTERVAL_DAY, pi); 

W ten sposób nie trzeba się martwić o ponowne ustawienie AlarmManager w Service.

Zwykle uruchamiam ten fragment kodu, gdy moja aplikacja się uruchamia (onResume w mojej głównej działalności) oraz w BroadcastReceiver skonfigurowanym do odbierania BOOT_COMPLETED.

pisałem przewodnik na tworzenie Service s i przy użyciu AlarmManager, która opiera się na własnym doświadczeniu i kilku wskazówek & sztuczki Wybrałem się od oglądania/O Google Talk i. Jeśli jesteś zainteresowany, możesz go przeczytać here.


Aby odpowiedzieć na to pytanie poniżej, wszystko co mogę zrobić, to cytat the docs:

public void setInexactRepeating (int type, long triggerAtTime, long interval, PendingIntent operation) 

Harmonogram powtarzający się alarm, który ma kod nie w pełni wymagania czasowe wyzwalania; na przykład alarm, który powtarza się co godzinę, ale niekoniecznie w szczycie każdej godziny. Alarmy te są bardziej energooszczędne niż ścisłe rekurencje dostarczane przez setRepeating (int, long, long, PendingIntent), ponieważ system może skorygować fazę alarmów, aby spowodować ich jednoczesne uruchamianie, unikając budzenia urządzenia z trybu uśpienia więcej niż to konieczne.

Pierwszy wyzwalacz alarmu nie będzie wyświetlany przed żądanym czasem, ale może nie wystąpić po prawie pełnym interwale po tym czasie. Ponadto, podczas gdy całkowity okres powtarzającego się alarmu będzie zgodny z żądaniem, czas pomiędzy dwoma kolejnymi uruchomieniami alarmu może być różny. Jeśli twoja aplikacja wymaga bardzo niskiego jittera, użyj zamiast tego setRepeating (int, long, long, PendingIntent).

Podsumowując, nie jest to zbyt jasne. Dokumenty mówią tylko, że alarm "może się różnić". Jednak ważne jest, aby wiedzieć, że pierwszy wyzwalacz może nie wystąpić przez prawie cały interwał po tym czasie.

+0

myślę, że usługa może być więcej niż muszę za to, co robię, ale Twój blog był dobry czytać! Czy zdajesz sobie sprawę z tego, ile zwykle ma offset SetInexactRepeating? – ninjasense

+1

Edytowałem swoją odpowiedź, aby wyjaśnić problem 'setInexactRepeating'. – Felix

+3

jako bonus, zamiast anulować przed ustawieniem nowego, można pobrać parametr PendingIntent z PendingIntent.FLAG_CANCEL_CURRENT jako ostatni parametr, który ma taki sam efekt. – nsL

4

to działa, to będzie strzelać alarm po każdych 5 sekund

private void setRecurringAlarm() { 

     Logger.d(IConstants.DEBUGTAG, "Setting Recurring Alarm"); 

     Calendar updateTime = Calendar.getInstance(); 

     updateTime.set(Calendar.SECOND, 5); 

     Intent alarmIntent = new Intent(this, AlarmReceiver.class); 
     PendingIntent recurringDownload = PendingIntent.getBroadcast(this, 0, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT); 
     AlarmManager alarms = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 
     alarms.cancel(recurringDownload); 
     alarms.setInexactRepeating(AlarmManager.RTC_WAKEUP, updateTime.getTimeInMillis(), 1000 * 5, recurringDownload); //will run it after every 5 seconds. 
    } 
+0

Jaka jest różnica między setInexactRepeating i setRepeating? –

+0

http://developer.android.com/reference/android/app/AlarmManager.html –

+1

Zaplanuj powtarzający się alarm, który ma niedokładne wymagania dotyczące czasu wyzwalania; na przykład alarm, który powtarza się co godzinę, ale niekoniecznie w szczycie każdej godziny. Alarmy te są bardziej energooszczędne niż ścisłe rekurencje dostarczane przez setRepeating (int, long, long, PendingIntent), ponieważ system może skorygować fazę alarmów, aby spowodować ich jednoczesne uruchamianie, unikając budzenia urządzenia z trybu uśpienia więcej niż to konieczne. –

Powiązane problemy