2011-09-02 12 views
6

Zaimplementowałem aplikację AlarmManager, aby obudzić telefon raz dziennie, aby wykonać zadanie aktualizacji, zaktualizować widżety i wysłać powiadomienia, jeśli dotyczy.Android AlarmManager setRepeating nie powtórzy się z długim interwałem

Używam setRepeating i ELAPSED_REALTIME_WAKEUP Alarm jest uruchamiany po raz pierwszy (SystemClock.elapsedRealtime()+60000) ale nie zostanie wyzwolony 86400000 milisekund (24 godzin) później.

Naprawdę borykając się z tym, jestem szczęśliwy, że mogę zrobić coś złego, lub jeśli istnieją lepsze sposoby osiągnięcia tego, co próbuję zrobić. Jednak myślę, że mój kod wygląda jak standardowa rzecz, którą ludzie wydają się robić.

To prawie tak, jak powtarzający się alarm nie robi tego, co powinno być we wszystkich przypadkach. Jeśli zmniejszę interwał, aby powiedzieć 10 minut, to działa, mój alarm uruchamia się i usługa jest prowadzona w kółko.

Charakter mojej aplikacji oznacza, że ​​aktualizacja więcej niż raz dziennie to przesada. Muszę znaleźć realistyczne, niezawodne rozwiązanie tego problemu.

Dzięki za poświęcony czas & mam nadzieję, że możesz wskazać mi właściwy kierunek.

Oto mój kod realizacja alarm ...

Oczywisty:

<receiver android:name=".SystemChangeReceiver"> 
    <intent-filter> 
     <action android:name="android.intent.action.BOOT_COMPLETED" /> 
     <action android:name="android.intent.action.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE" /> 
    </intent-filter> 
</receiver> 
<receiver android:name=".UpdateAlarmReceiver" /> 
<service android:name=".UpdateService" /> 
<receiver android:name=".WidgetProviderSmall" android:label="@string/widget_small_label"> 
    <intent-filter> 
     <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> 
    </intent-filter> 
    <meta-data 
     android:name="android.appwidget.provider" 
     android:resource="@xml/appwidget_small" /> 
</receiver> 
<receiver android:name=".WidgetProviderLarge" android:label="@string/widget_large_label"> 
    <intent-filter> 
     <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> 
    </intent-filter> 
    <meta-data 
     android:name="android.appwidget.provider" 
     android:resource="@xml/appwidget_large" /> 
</receiver> 

SystemChangeReceiver nasłuchuje transmisji startowego, sprawdza, czy alarm musi być ustawiony, jeśli tak, to ustawia go.

SystemChangeReceiver:

@Override 
public void onReceive(Context context, Intent intent) { 

    SharedPreferences prefs = context.getSharedPreferences(context.getString(R.string.prefs_name), 0); 

    Boolean notifications = prefs.getBoolean("enable_updates", false); 
    if(notifications == true) { 
     Utils.setNotificationAlarm(context); 
    } 
} 

Sposób setNotificationAlarm, konfiguruje powtarzania alarmu ...

public static void setNotificationAlarm(Context context) { 
     AlarmManager alarmManager=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE); 

     Intent intent = new Intent(context, UpdateAlarmReceiver.class); 
     PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0); 

     alarmManager.setRepeating(
      AlarmManager.ELAPSED_REALTIME_WAKEUP, 
      SystemClock.elapsedRealtime()+60000, 
      86400000, 
      pi); 
} 

Gdy alarm uruchamia mój odbiornik UpdateAlarmReceiver zdecyduje co robić i za pomocą WakefulIntentService biegnie mój aktualizacji w tle przetwarzanie, moduł obsługi dla usługi aktualizuje widżety i wysyła wymagane powiadomienia

UpdateAlarmReceiver:

public void onReceive(Context context, Intent intent) { 
    WakefulIntentService.sendWakefulWork(context, UpdateService.class); 
} 
+0

Szybkie pytanie, które może rozwiązać to wszystko: Czy używasz zabójcy zadań? Czy Twoja aplikacja znajduje się na białej liście? –

+0

Używam AutoKiller Memory Optimizer, nie ma białej listy, to może być problem? Moja aplikacja działa nadal zgodnie z listą procesów. – Rob

Odpowiedz

1

Czy próbowałeś ustawić, aby nie powtarzać. Następnie, kiedy odpalisz, ustaw następny alarm pojedynczego strzału na 24 godziny później? Będzie to działać jak powtarzający się alarm, ale może uniknąć niektórych problemów, które widzisz.

+0

Nie rozważałem tego. Myślałem, że to w zasadzie to, co zrobił setRepeating. Dam ci spróbować, dzięki. – Rob

+0

Zrobiłem aplikację typu budzik i tak ją obsłużyłem i wydawało mi się, że działa poprawnie, podpowiadając urządzeniu AlarmActivity, aby uruchomił się we właściwym czasie następnego dnia. Nigdy nie użyłem flagi setRepeating(), więc nie jestem pewien, dlaczego to nie zadziała, wydaje mi się, że te dwa podejścia powinny działać tak samo. Czy to możliwe, że nie budzi urządzenia poprawnie, gdy się uruchamia? – FoamyGuy

+0

Myślę, że to dobrze się budzi, ja używam 'WakefulIntentService', która używa' PowerManager.WakeLock' – Rob

2

Nie ma niczego oczywiście nie tak.

Jednak przez tak długi okres zalecam RTC_WAKEUP, aby można było go ustawić w środku nocy lub w wybranym przez użytkownika czasie, a nie co 24 godziny -random punkt początkowy. Jest możliwe, że RTC_WAKEUP zapewnia lepsze wyniki.

również:

  • Dodaj oświadczenie logowania do onReceive() z UpdateAlarmReceiver aby potwierdzić, czy są coraz kontrolę w ogóle, czy problem jest (gasp!) Z WakefulIntentService.
  • Spróbuj systematycznie zwiększać swój okres. Ponieważ mówisz, że 10 minut działa, spróbuj godzinę, potem cztery godziny itd. I spróbuj zrozumieć, kiedy się zepsuje.
  • "Używam AutoKiller Memory Optimizer, ale nie mam białej listy, to może być problem? Moja aplikacja działa jednak zgodnie z listą procesów." - Wyłączałbym wszystkich zabójców zadań, aby upewnić się, że nie przeszkadzają.
+0

Dzięki Mark, już dodałem logowanie w różnych miejscach, z długim interwałem nawet nie uderzając w odbiornik alarmu, więc jestem pewien, że to menadżer alarmu gdzieś w błędzie. Wyłączyłem teraz optymalizator pamięci, źle wypróbuję wszystkie inne sugestie. – Rob

+0

@Rob: Jedyne co wiem o tym, że pozbywam się zaplanowanego alarmu to: jeśli "anulujesz()" to, jeśli użytkownik wymusi zatrzymanie go z zarządzania usługami w aplikacji Ustawienia, lub jeśli zabójca zadania je zatrzyma (i to może być problem tylko w wersji 2.1 i wcześniejszych - nie oczekiwałbym, że 'killBackgroundProcesses()' usunie alarmy, ale mogę się mylić). Mam nadzieję, że przekonasz się, że to AutoKiller był winowajcą. – CommonsWare

Powiązane problemy