NA CZYM POLEGA PROBLEM:
W czasie gdy telefon jest uśpiony i jednocześnie połączony w siecią WIFI powiadomienia push, albo dochodzą z dużym opóźnieniem, albo wcale. Problem dotyczy systemu Android w wersji od 4.1 do nawet 4.2.2 (użytkownicy Nexusa 4 również narzekają). Dzieje się tak w przypadku większości sieci bezprzewodowych.
WYJAŚNIENIE:
Push w systemie Android działa na zasadzie podtrzymywania połączenia TCP na porcie 5228 poprzez regularne (co 15 min. na WiFi i co 28 min. na 3G) wysyłanie małego pakietu danych (tzw. heart beat). Problem pojawia się w momencie gdy telefon wchodzi w stan uśpienia i pozostaje w nim przez dłuższy czas - wtedy ten 15-minutowy interwał może okazać się za długi i w międzyczasie router/serwer zarządzający siecią bezprzewodową zrywa połączenie z powodu braku aktywności. W takiej sytuacji wysłanie kolejnego pakietu (heart beat) zakończy się niepowodzeniem, a co za tym idzie powiadomienie push o nowej poczcie nie dotrze, aż do wybudzenia telefonu, odświeżenia wpisu w tablicy ARP routera/serwera i pomyślnego wysłania kolejnego pakietu (zgodnie z harmonogramem).
PRZYCZYNA:
Wadliwe sterowniki WIFI zaimplementowane w systemie Android od wersji JB. Mimo, iż Google jest świadome występowania problemu nawet w Nexusie, aktualizacja sterownika nastąpi prawdopodobnie dopiero w Key Lime Pie.
ROZWIĄZANIE:
Przedstawione poniżej rozwiązania są raczej obejściami, niż faktycznymi rozwiązaniami problemu jednak w niektórych przypadkach mogą okazać się pomocne. Dwa pierwsze przetestowałem na sobie i obydwa działają.
1) Wyłączenie podtrzymywania połączenia WIFI w czasie uśpienia i korzystanie z transmisji danych. Nie jest to idealne wyjście ponieważ po pierwsze skraca żywotność baterii, a po drugie może narazić na koszty w przypadku braku odpowiednio dużego pakietu danych. Powiadomienia w sieci 2G/3G/4G dochodzą bez problemów.
2) Przypisanie na stałe adresu IP do naszego urządzenia na routerze/serwerze i oczywiście otwarcie portu 5228 (nie zawsze jest otwarty - można także dodać telefon do strefy DMZ, ale nie zalecam takiego rozwiązania). To również nie jest idealne rozwiązanie ponieważ działa tylko w domu czy pracy, a i tu nie zawsze istnieje możliwość dokonania takich zmian w konfiguracji.
3) Instalacja programu "Push Notifications Fixer" z Google Play, zmieniającego interwał wysyłania pakietu heart beat z 15 na 5 minut. Nie testowałem tego rozwiązania ponieważ wymagany jest root urządzenia, mam też wątpliwości czy działanie tego programu w tle nie spowoduje większego zużycia energii...
Istnieje jeszcze jedno rozwiązanie, mianowicie zmiana ROMu/jądra na zawierający/e poprawione sterowniki jednak ten temat dotyczy konkretnych modeli (do Nexusa można znaleźć na XDA, do innych modeli nie sprawdzałem).