Jak działają i czym są powiadomienia push w Androidzie?

Paweł Dedio Programowanie 2018-11-10

Witajcie w kolejnym odcinku naszej programistycznej serii. Dzisiaj zajmiemy się czymś, co wydaje się proste z perspektywy użytkownika. Jednak z perspektywy programisty wymaga nieco wysiłku. Chodzi oczywiście o tytułowe powiadomienia push. Zacznijmy od kilku słów teorii.

Czym są powiadomienia push?

W dzisiejszych czasach powiadomieniem push nazywa się każde powiadomienie, które możesz zobaczyć na swoim telefonie lub innym urządzeniu. Jednak jeśli chcemy być dokładni, to nie każde powiadomienie jest pushem. W Androidzie powiadomienia możemy podzielić na dwa rodzaje: powiadomienia utworzone przez aplikację oraz te przysłane przez zewnętrzny serwer. To właśnie ten drugi rodzaj powiadomienia nazywamy powiadomieniami push.

W jaki sposób aplikacja wyświetla powiadomienia?

Powiadomienia są wyświetlane nie tylko przez programy, które korzystają z dostępu do internetu. Jako przykład mogę tutaj podać aplikację budzika, z której korzystam. Mianowicie aplikacja ta co niedzielę wyświetla powiadomienie z przypomnieniem o nastawieniu budzika na poniedziałek. Jak to działa pod spodem? Jeśli aplikacja wykryje w niedzielę, że nie ustawiłem żadnego budzika na poniedziałek, wysyła do systemu żądanie o wyświetlenie notyfikacji wraz z odpowiednimi parametrami (tytuł, tekst, obrazek i tak dalej). Do takiego działania nie potrzebujemy żadnej ingerencji zewnętrznego serwera. Technicznie rzecz biorąc, nie powinniśmy nazywać takiego powiadomienia powiadomieniem push. Programista może w dowolnym miejscu zadecydować o wyświetleniu dowolnego powiadomienia.

Jakie jest przeznaczenie powiadomień push?

Patrząc dość ogólnie, powiadomienia push są przykładem jednostronnej komunikacji serwera z naszą aplikacją. Wyobraźmy sobie taki życiowy przykład — chcemy wyświetlić użytkownikowi informację, że otrzymał właśnie wiadomość w naszej aplikacji. Da się to zrobić na dwa sposoby. Możemy w określonych przedziałach czasowych łączyć się z naszym serwerem i pobierać informację o nieodczytanych wiadomościach. W sytuacji, gdy takie istnieją, wyświetlimy powiadomienie z odpowiednim komunikatem. Łatwo się domyślić, że nie jest to zbyt dobre rozwiązanie. Przede wszystkim takie regularne łączenie się z serwerem będzie powodować zużycie akumulatora i pakietu internetowego. Drugim rozwiązaniem jest wysłanie powiadomienia bezpośrednio z naszego serwera w momencie otrzymania wiadomości przez konkretnego użytkownika. Jak widać metoda druga, czyli powiadomienia push pozwala wyeliminować marnowanie energii i pakietu internetowego. To dlatego takie powiadomienia są tak powszechnie stosowane.

Jak wygląda obsługa przychodzących powiadomień z perspektywy programisty?

Obecnie można to zrobić na dwa sposoby — wszystko zależy od tego, czy jesteś prawdziwym fanem Androida i wolisz mieć kontrolę nad urządzeniem, czy nie. Pierwsze podejście jest bardzo podobne do mechanizmu obecnego w systemie iOS. Jeśli nasza aplikacja jest w tle i serwer wyśle powiadomienie, to system automatycznie wyświetli je za nas. Jeśli jednak nasza aplikacja jest aktualnie uruchomiona, to sami musimy obsłużyć odebrane informacje i poprosić system o wyświetlenie powiadomienia z odpowiednimi atrybutami. W drugim podejściu całą obsługę wyświetlania powiadomień bierzemy na siebie bez względu na to, czy nasza aplikacja jest obecnie w tle, czy nie.

Ręczna obsługa powiadomień — czy to trudne?

Nie jest to trudne, Google uprościło to praktycznie najbardziej, jak to się dało. Wystarczy, że rozszerzymy odpowiednią klasę udostępnioną przez Google i zaimplementujemy metodę odpowiadającą za odebranie powiadomienia. Późniejsze kroki wyglądają tak samo, jakbyśmy pokazywali zwykłą notyfikację offline (taką jak w przytoczonym przykładzie z budzikiem). Największą przeszkodą jest przekopanie się przez dokumentację Google i odpowiednie skonfigurowanie naszej aplikacji — dodanie odpowiednich kluczy licencyjnych, bibliotek i tak dalej. Niestety większość dokumentacji usług dodatkowych Google jest napisana bardzo tragicznie i trzeba szukać pomocy na innych serwisach.

W jaki sposób serwer rozpoznaje konkretne urządzenie?

powiadomienia push bzwbk

Odpowiadając na to pytanie, najpierw muszę przedstawić Wam, jak wygląda wysyłanie powiadomień z perspektywy serwera. Nasz serwer nie łączy się z naszymi telefonami bezpośrednio, wszystko przechodzi przez serwery Google. Po pierwsze nasz serwer oraz aplikacja potrzebują otrzymać od Google klucz licencyjny — pozwala on na identyfikacje naszej aplikacji. W momencie, gdy serwer chce wysłać powiadomienie, łączy się z serwerem Google i przekazuje właśnie ten klucz licencyjny. W ten sposób Amerykanie wiedzą, do której aplikacji kierować powiadomienie. To nie wszystko, aby otrzymywać powiadomienia w naszej aplikacji. Musimy zalogować użytkownika do obsługi pushy, przekazując klucz licencyjny do serwerów Google. W odpowiedzi otrzymujemy unikalny klucz, który identyfikuje nasze urządzenie. W tym momencie musimy przekazać go do naszego serwera. Brzmi to trochę zagmatwanie, więc przedstawię to na podstawie listy kroków:

  1. Użytkownik loguje się w naszej aplikacji
  2. Otwieramy ekran powitalny i jednocześnie logujemy użytkownika (dodając do zapytania klucz licencyjny) do usługi Google odpowiedzialnej za powiadomienia.
  3.  Wysyłamy otrzymany od Google klucz identyfikujący urządzenie do naszego serwera wraz z danymi aktualnie zalogowanego użytkownika
  4. Serwer przypisuje klucz urządzenia do danego użytkownika
  5. Użytkownik dostaje wiadomość
  6. Serwer wysyła żądanie wysłania powiadomienia wraz z kluczem licencyjnym, kluczem urządzenia i odpowiednią wiadomością
  7. Google sprawdza, czy klucz urządzenia i klucz licencyjny są poprawne i wysyła powiadomienie na urządzenie.
  8. Obsługujemy powiadomienie w naszej aplikacji

Dlaczego powiadomienia się nie dublują?

Pewnie nieraz zauważyłeś, że w chwili, gdy odczytasz maila na komputerze, znika odpowiednie powiadomienie wyświetlone na wszystkich Twoich urządzeniach. Pewnie zastanawiałeś się, jak to się dzieje — już śpieszę z wyjaśnieniem. Z perspektywy serwera nie ma jakiegoś standardu, który określałby jak coś takiego wykonać, więc musimy zrobić to ręcznie. Przeważnie logika działania jest bardzo podobna. W momencie, gdy serwer wykryje odczytanie jakiejś wiadomości przez użytkownika, wysyła nowe powiadomienie push z odpowiednimi danymi do wszystkich urządzeń dodanych przez użytkownika. Aplikacja rozpoznaje, że jest to specjalne powiadomienie, które oznacza odczytanie wiadomości. Zamiast wyświetlać jakieś nowe powiadomienie, aplikacja komunikuje się z systemem Android i usuwa powiadomienie odpowiedzialne za odczytanie tej konkretnej wiadomości.

android n powiadomienia bezposrednia odpowiedz

Jest jeszcze jedna opcja, nieco prostsza. Google udostępnia taką usługę jak grupowanie urządzeń. Dzięki temu możemy przypisać do 20 urządzeń do jednego użytkownika i zamiast ręcznie wysyłać powiadomienia do każdego urządzenia, możemy je wysłać do tej właśnie grupy. Google już zadba o to, że powiadomienia będą widoczne na wszystkich urządzeniach i w przypadku odczytania go na jednym z urządzeń, zniknie ono również na pozostałych.

Dzięki za dzisiaj. Widzimy się tradycyjnie za tydzień. Opowiem Wam, w jaki sposób aplikacje pobierają dane z zewnętrznych serwisów i co to takiego jest API. Tradycyjnie zachęcam do komentowania i pisania propozycji tematów, o których chcielibyście poczytać w nadchodzących odcinkach.

Zapraszam również na największe w Polsce forum dla programistów Android. Jeśli macie pytania odnośnie do kariery jako programista — zapraszam do działu Kariera programowanie. Zachęcam również do przejrzenia działu Praca oraz zlecenia dla programistów — być może to właśnie tam znajdziesz swoją pierwszą pracę.

Dziel się tym, co lubisz — ucz programowania!

Coders Lab — Szkoła IT rekrutuje wykładowców — podejmij ich wyzwanie i rozwiń się jako programista. Technologie, których możesz uczyć na kursach to Front-end (m.in. JavaScript, React.js), Back-end (Python, PHP, Java, C# (.NET)), User Experience oraz Testowanie: Manualne i Automatyczne. O tym, jakie korzyści płyną z pracy jako wykładowca w Coders Lab — Szkole IT możesz przeczytać tutaj.

Poprzednie odcinki:

  1. Typowy dzień pracy programisty
  2. Wady pracy programisty
  3. Zalety pracy programisty
  4. [FAQ] Wszystko, co powinieneś wiedzieć jeśli interesuje Cię praca programisty
  5. Co mnie zdziwiło w programowaniu?
  6. Motywacje – w jaki sposób nie stracić zapału do programowania?
  7. Jaką firmę wybrać na początku kariery programisty?
  8. Jak wygląda rozmowa o pracę na stanowisko programisty?
  9. Jak zacząć programować?
  10. Skąd czerpać wiedzę o programowaniu?
  11. Początki programowania – jaką technologię wybrać?
  12. Cykl życia aplikacji na Androida – co to takiego?
  13. Jak tworzymy interfejs użytkownika w aplikacjach na Androida?
  14. Jak system Android oszczędza energię?


  • Tomasz

    Tego typu powiadomienia wymagaja stalej obecnosci w sieci. Zadalem sobie pytanie : co mi potrzeba zawsze? Tak naprawde informacji ze ktos do mnie dzwoni oraz ze przyszedl sms. Tak wiec cala reszte ustawiam na manual i odczytuje stan i wiadomosci w momencie odblokowania ekranu przez wifi jesli jest dostepne albo mobile. Dzieki temu przy wylaczonym ekranie mam i wifi i mobile net wylaczony. A wszystko to robie skryptem automagica. Celem tego jest niepobieranie energi, gdy ze sprzetu aktywnie nie korzystam.

    • Paweł Dedio

      Dobre podejście. Sam też minimalizuję ilość otrzymywanych powiadomień. Czytałem sporo artykułów o tym jak wyłączenie wszystkich powiadomień poprawia naszą produktywnosc, ponieważ nie jesteśmy odrywani od pracy. Muszę przyznać, że coś w tym kesy.

      • szafran

        Zgadza się. W sumie te nowe funkcje w Androidzie i iOS typu „czas przed ekranem” też są przydatne. Daje do myślenia jak zorientujesz się,, np. wybudzasz telefon np ŚREDNIO co 6 minut :O

    • Dobra sprawa. Sam muszę chyba nad czymś podobnym pomyśleć 🙂