2016-01-06 21 views
10

Mam BroadcastReceiver, który zmienia harmonogram alarmów w przypadku zdarzeń, takich jak ładowanie i zmiana czasu. Ale gdy minie czas wyzwalania alarmu (na przykład, gdy użytkownik ręcznie zmienia czas z ustawień), AlarmManager uruchamia alarm natychmiast, zanim będę mógł dodać dzień, aby zmienić harmonogram alarmu. Jak mogę tego uniknąć?AlarmManager uruchamia alarmy w przeszłości bezpośrednio, zanim BroadcastReceiver może je zmienić.

Obecnie używam zestawu i dodaj metody Calendar, aby zaplanować alarmy.

 for (int dayOfWeek = Calendar.SUNDAY; dayOfWeek <= Calendar.SATURDAY; dayOfWeek++) { 
      if (alarm.getRepeatingDay(dayOfWeek - 1) && dayOfWeek >= nowDay && 
        !(dayOfWeek == nowDay && alarm.timeHour < nowHour) && 
        !(dayOfWeek == nowDay && alarm.timeHour == nowHour && alarm.timeMinute <= nowMinute)) { 

       calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek); 
       alarmSet = true; 
       break; 
      } 
     } 

     if (!alarmSet) { 
      for (int dayOfWeek = Calendar.SUNDAY; dayOfWeek <= Calendar.SATURDAY; dayOfWeek++) { 
       if (alarm.getRepeatingDay(dayOfWeek - 1) && dayOfWeek <= nowDay) { 
        calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek); 
        calendar.add(Calendar.WEEK_OF_YEAR, 1); 
        break; 
       } 
      } 
     } 

Jest również powiedziane w docs:

Jeśli czas wyzwalania podanymi w przeszłości, alarm zostanie wyzwolony natychmiast.

Jak to zachowanie można zmienić?

+0

Proponuję użyć JobScheduler, jak można pozbyć się problemu zamieszczonego BroadcastReceiver. – UMESH0492

Odpowiedz

4

Jest to przeznaczone. Zobacz np. Set a Repeating Alarm

Czas wyzwalania. Jeśli określony czas wyzwalania jest w przeszłości, alarm uruchamia się natychmiast.

lub samo here

Jeśli czas wyzwalania podanymi w przeszłości, alarm zostanie uruchomiony natychmiast.

Aby tego uniknąć trzeba będzie ręcznie sprawdzić alarmy przed dodaniem ich

if(alarmTimeStamp < System.currentTimeMillis()) { 
    // if is repeating schedule in __interval__ 
    // else ignore 
} 

lub zignorować je w odbiorniku, jeżeli data jest w przeszłości.

+0

Wiem, czytałem dokumenty. Ale wyraźnie chcę, aby temu zapobiec. – Piyush

+0

@PiyushShrivastava właśnie zaktualizował odpowiedź. Będziesz musiał sam przeprowadzić sprawdzanie daty, ponieważ nie ma żadnego ogólnego rozwiązania. –

+0

Zaimplementowałem sprawdzanie daty. Problem polega jednak na tym, że menedżer alarmów uruchamia alarm, zanim mój odbiornik zostanie wywołany. Jak mogę wezwać odbiorcę przed tym? – Piyush

0

Jak stwierdził David, sprawdź datę/godzinę alarmu przed użyciem; jeśli jest w przeszłości, dodaj sekundę, minutę lub cokolwiek, zanim podasz je do AlarmManager.

Jeśli użytkownik wprowadza datę/godzinę, należy wstępnie sprawdzić wejście w ten sam sposób.

+0

Wstępne sprawdzenie wejścia jest możliwe tylko wtedy, gdy użytkownik zmieni godzinę alarmu. Nie, jeśli czas zmienił się z ustawień. – Piyush

0

Co powiesz na tworzenie BroadcastReceiver do słuchania zmiany czasu.

W Manifest pliku

<receiver android:name=".MyReceiver"> 
      <intent-filter > 
       <action android:name="android.intent.action.TIME_SET"/> 
      </intent-filter> 
</receiver> 

i plik

public class MyReceiver extends BroadcastReceiver{ 

    @Override 
    public void onReceive(final Context context, Intent intent) { 
     Log.d("MyReceiver", "Time Changed"); 
     // The times have changed; so have their signs. 
     updateYourAlarm(); 
    } 
} 
+0

Mam już akcje TIME_SET i DATE_CHANGED dodane w manifeście. Problem nadal występuje. – Piyush

+0

Program BroadcastReceiver onReceive wywołuje wiele razy podczas ręcznej zmiany daty lub godziny, w manifeście używam tych dwóch jako filtrów zamiaru TIME_SET i DATE_CHANGED –