Broadcast Receiver w Androidzie – co to takiego?

W dzisiejszym artykule zapoznamy się z tak zwanym BroadcastReceiverem zaimplementowanym w Anroidzie. Jest to mechanizm, który umożliwia komunikację między systemem, a komponentami naszej aplikacji. Rozwiązanie to wykorzystywane jest również, do wewnętrznej komunikacji w aplikacji oraz całym systemie (można je wykorzystać na przykład do przekazywania danych między dwoma różnymi programami). Pewnie brzmi skomplikowanie? Ale na szczęście tak nie jest, zobaczycie zresztą sami…

Fot: nyphotographic.com, CC BY-SA 3.0.

Fot: nyphotographic.com, CC BY-SA 3.0.

BroadcastReceiver – implementacja

BroadcastReceivera w aplikacji możemy zaimplementować na dwa sposoby. Jako oddzielną klasę rozszerzającą BroadcastReceiver (wcześniej rejestrując ją w manifeście), na przykład w ten sposób:

lub jako klasę zagnieżdżoną (przykładowo umieszczając kod w metodzie):

UWAGA: Klasę zagnieżdżoną z BradcastReceiver możemy zaimplementować tylko i wyłącznie w komponencie (np. aktywności).

Na czym będziemy pracować?

Ok, wiemy już jak zaimplementować BroadcastReceivera w projekcie, teraz pora przejść do jakiegoś praktycznego przykładu. Jak zwykle aby nie tracić czasu utworzymy sobie w Android Studio pusty projekt, na którym będziemy dalej pracować (tworzenie projektów opisywałem w tym artykule). Oczywiście przyda nam się również kontrolka umożliwiająca wyświetlanie tekstu (np. TextView) wstawiamy więc ją na środku głównego ekranu aplikacji.

Wersja dla leniwych jest do pobrania tutaj (projekt wykonany w Android Studio 2.2).

Problem…

Chcemy wkorzystać BroadcastRecivera do rozwiązania jakiegoś problemu, załóżmy więc, że potrzebujemy aby w naszej aplikacji wyświetlała się informacja o podpięciu telefonu do ładowarki (rozpoczęciu ładowania) i odłączeniu telefonu od źródła zasilania (zakończenie ładowania), a kiedy telefon jest podpięty do ładowarki chcemy aby program wyświetlał odpowiedni komunikat na ekranie.

Rejestracja BroadcastReceivera w manifeście

Pierwszym krokiem od jakiego zaczniemy jest rejestracja Receivera. Należy to zrobić w manifeście. Po otwarciu naszego projektu w Android Studio przechodzimy więc do pliku AndroidManifest.xml znajdującego się w katalogu manifest i otwieramy go.

Następnie wewnątrz tagu <applcation ...> ... </application> wstawiamy taki tekst:

Jak widać, zrobiłem przerwę w 4 i 5 linijce, nie bez powodu. W to miejsce wstawimy ten kod:

Umożliwia on nam dostęp do informacji o zdarzeniu „podłączenia ładowarki” (linijka 1) oraz „odłączenia ładowarki” (linijka 2).

Całość prezentuje się następująco:

W 12 linijce powyższego kodu IDE w którym pracujemy powinno poinformować nas o błędzie. Chodzi między innymi o to, że odwołujemy się tutaj do klasy MyReciver, która nie istnieje.

Tworzymy więc odpowiednią klasę w projekcie:

i implementujemy metodę onReceive():

Obsługa zdarzeń przez BroadcastReceivera

W metodzie onReceive() zrobimy obsługę naszych zdarzeń. Chcemy aby na ekranie wyświetlał się komunikat informujący nas o tym, że podłączyliśmy telefon do ładowarki. Korzystamy więc z obiektu intent (który otrzymujemy jako argument) i wywołujemy na nim metodę getActions(), kolejnym elementem jest sprawdzenie czy jest to zdarzenie, które chcemy obsłużyć czyli android.intent.action.ACTION_POWER_CONNECTED (podłączenie telefonu do źródła zasilania), robimy to za pomocą wbudowanej w Jave metody equals():

Ok, teraz pozostało nam tylko wyświetlić odpowiedni komunikat:

Nasz program już praktycznie działa. Możemy teraz uruchomić aplikację na telefonie, włączyć ją i podłączyć telefon do ładowarki, a otrzymamy stosowną informację o tym wydarzeniu.

UWAGA: Kiedy zamkniemy aplikację (ale dalej będzie ona zainstalowana w systemie) i podłączymy telefon do źródła zasilania, również zostaniemy o tym poinformowani odpowiednim komunikatem.

UWAGA: BroadcastReceiver zarejestrowany w Manifeście działa niezależnie od tego, czy aplikacja jest uruchomiona czy nie.

Analogicznie dodajemy obsługę zdarzenia informującego o odłączeniu ładowarki:

MyReciver, który stworzyliśmy wyświetla tylko komunikaty informujące o podłączeniu ładowarki bądź jej odłączeniu. Nie możemy za jego pomocą wyświetlić w aplikacji stałej informacji mówiącej o tym, że telefon jest właśnie w trakcie ładowania. Dzieje się tak dla tego, że BroadcastReceiver został zarejestrowany w manifeście, a więc będzie działał nawet jak nasz program jest obecnie wyłączony. Gdybyśmy teraz chcieli w jakiejś kontrolce z MainActivity wyświetlić tekst doszło by do błędu.

BroadcastReceiver w Aktywności

Naszym celem jest jednak wyświetlanie stałej informacji o tym, że telefon jest w trakcie ładowania. Aby to zrobić musimy skorzystać z drugiej implementacji BroadcastReceivera czyli zarejestrować go w Aktywności. Wtedy taki BroadcastReceiver działa tylko jeżeli dana aktywność jest aktywna.

Jak to zrobić? Pierwszym krokiem będzie umieszczenie klasy zagnieżdżonej BroadcastReceiver w metodzie onCreate wybranej aktywności (zgodnie z przykładem na początku artykułu):

Aby nasz BroadcastReceiver był obsługiwany musimy go zarejestrować oraz „poinformować” system, jakie zdarzenie ma obsługiwać:

Jak widać, użyliśmy do tego metody registerReceiver() gdzie jako pierwszy argument podaliśmy obiekt reprezentujący nasz BroadcastReceiver, a jako drugi argument podaliśmy obiekt IntentFilter z informacją, że zdarzenie które chcemy obsłużyć to ACTION_POWER_CONNECTED (podłączenie telefonu do ładowarki).

Pozostało tylko dopisać obsługę komunikatu:

UWAGA: Obiekt textView używamy teraz w innej klasie, aby więc wszystko działało przy jego inicjalizacji musimy dopisać słowo kluczowe final.

Analogicznie robimy drugiego BroadcastReceivera obsługującego zdarzenie odłączenia ładowarki:

Cały kod metody onCreate():

Nasz program jest już gotowy możemy go uruchomić i zobaczyć jak działa.

Ukończony projekt do pobrania tutaj.

, , , , , , , , , , ,