2012-09-24 15 views
5

Piszę aplikację dla systemu Android, na której użytkownik może wybrać kilka zasobów do obejrzenia i otrzyma powiadomienie, jeśli zostanie dopasowany predefiniowany warunek alertu. Dane zapasów są zapisywane w 5 obiektach niestandardowego alertu klasy paczkowej (jeden obiekt na stan i warunek). Okresowa aktualizacja danych odbywa się za pośrednictwem usługi uruchomionej przez Menedżer alarmów. Obiekty alertów są przekazywane do usługi poprzez umieszczenie ich w intencji, która jest wprowadzana do PendingIntent w Menedżerze Alarmowym.Jak zaktualizować dane wysyłane do usługi za pomocą intencji, gdy usługa jest uruchamiana przez menedżera alarmów?

Intent intent = new Intent(this, UpdateService.class); 
    Bundle b = new Bundle(); 
    saveAlertsToBundle(b);  
    intent.putExtras(b); 
    intent.setData(Uri.parse("updateManager")); 
    PendingIntent pendIntent = PendingIntent.getService(this,0,intent,0); 

    // 1min intervall 
    long intervall = DateUtils.MINUTE_IN_MILLIS * 1; 
    // time of first start 
    long firstStartDelay = DateUtils.SECOND_IN_MILLIS * 30; 
    long firstStart = System.currentTimeMillis() + firstStartDelay; 

    AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 
    // kill running 
    am.cancel(pendIntent); 
    //start new 
    am.setRepeating(AlarmManager.RTC_WAKEUP,firstStart,intervall,pendIntent); 

Mój problem jest:

Uruchamiając usługę po raz pierwszy, gdy istnieje tylko jeden obiekt ostrzegania przeszedł do służby wszystko działa poprawnie. Gdy tylko istnieje więcej obiektów alertów, muszą one również zostać przekazane do usługi, ale nie działa to z powyższym kodem. Usługa nie otrzymuje zaktualizowanego celu z dodatkowymi obiektami alertów, ale tylko początkowy z tylko jednym obiektem alertu. Powyższy kod poprawnie tworzy intencję z dodatkowym obiektem alertu, ale nigdy nie dostanie się do usługi.

Moje pytanie brzmi: jak przekazać zaktualizowane intencje do już uruchomionego programu AlarmManager.

Próbowałem już zatrzymać znak AlarmManager (wiersz w // komentarzu Zabijanie) i zrestartować go, ale to nie działa. Być może z powodu zamiaru nie posiadania tych samych obiektów alarmowych, co w momencie, kiedy został stworzony? Próbowałem to naprawić, ustawiając uri w części danych intencji, ale to też nie pomogło.

Dzięki za pomoc.

Odpowiedz

2

Twój problem jest taki, jak działa PendingIntent. System zarządza pulą PengingIntent s. Gdy twój kod robi.

PendingIntent pendIntent = PendingIntent.getService(this,0,intent,0); 

To powoduje, że system wyszukać PendingIntent pasującej parametry przeszedłeś w (w tym przypadku, twój Intent Jednak algorytm dopasowywania że PendingIntent wykorzystuje porównuje tylko niektóre pola z Intent, aby określić, czy jest to ten, którego szukasz. W szczególności, nie porównuje dodatków. Oznacza to, że po utworzeniu pierwszego numeru PendingIntent, wywołanie do PendingIntent.getService() zawsze zwróci ten sam numer PendingIntent z puli (i nie twórz nowej, czyli tego, czego chcesz).

W celu wywołanie PendingIntent.getService() utworzyć nowy PendingIntent za każdym razem to nazwać, spróbuj parametry, które przechodzą do rozmowy wyjątkowy, tak:

int requestCode = (int) System.currentTimeMillis(); // Create unique request code 
PendingIntent pendIntent = PendingIntent.getService(this, requestCode, intent, 0); 

Od requestCode będą różne dla każdego wywołania PendingIntent.getService(), powinno to rozwiązać twój problem.

EDIT podstawie wypowiedzi OP poniżej

Chcesz anulować istniejący alarm i tworzyć nowe z nowymi danymi. W takim przypadku nie musisz używać unikalnych identyfikatorów, ponieważ chcesz mieć tylko jedną PendingIntent w puli. Ale chcesz zmienić dane na ten temat.Wypróbuj to:

// Create a PendingIntent (or update the existing PendingIntent with new values 
PendingIntent pendIntent = PendingIntent.getService(this, 0, intent, 
         PendingIntent.FLAG_UPDATE_CURRENT); 

AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 
// cancel any pending alarms 
am.cancel(pendIntent); 
//start new 
am.setRepeating(AlarmManager.RTC_WAKEUP,firstStart,intervall,pendIntent); 
+0

Dziękuję za pomoc, to rozwiązało problem, ale utworzyło nowy. Dodatkowe obiekty alertów są przekazywane do usługi, ale jako dodatkowe usługi kontrolowane przez program AlarmManager działają już uruchomione programy AlarmManagers. Dlatego liczba alarmowych menedżerów wzrasta za każdym razem, gdy dodaję obiekt alertu. Oznacza to, że jeden działa dla jednego obiektu alertu, jeden dla dwóch, jeden dla trzech itd. Myślę, że byłoby lepiej, gdyby był tylko jeden z bieżącą ilością istniejących alarmów, więc nadal muszę zatrzymać starego AlarmManagera. Usługi są zatrzymywane za pomocą wywołania metody stopSelf(). – user1695117

+0

OK. Nie byłem pewien, co dokładnie chcesz zrobić. Na podstawie tego komentarza wydaje się, że chcesz anulować istniejący alarm i utworzyć nowy z nowymi parametrami. Będę edytować moją odpowiedź na to. –

+0

To działało idealnie. Więc wszystko, czego mi brakowało, to poprawna flaga, jak się wydaje. Dziękuję za pomoc. – user1695117

Powiązane problemy