Powiadomienia z telefonu i IFTTT.com

Jak dużo powiadomień generuje Android? Dzisiaj dość proste zadanie, ale może być interesujące. Od kilku lat jestem użytkownikiem i fanem serwisu If This The That który pozwala na automatyzację wielu zadań. W skrócie polega to na tym, że podpinamy do IFTTT.com swoje konta, aplikacje, urządzenia (żarówki, samochody - bo czemu nie?) i budujemy przepisy (applets). Każdy przepis to zawsze dwa elementy: wyzwalacz i akcja. Na przykład: jeśli temperatura spadnie poniżej 5 stopni (wyzwalacz) to wyślij maila (akcja). Możemy łączyć ze sobą kilka serwisów (jeśli dodam nowe zdjęcie na Instagramie to zapisz je w Dropboxie), informować o czymś mailem (wyślij maila jeśli prognoza według Weather Underground przewiduje deszcz), zapisywać historię zdarzeń (wszystkie moje twitty zapisz do arkusza Google) czy też zarządzać telefonem (włącz wi-fi jeśli jestem w rejonie oznaczonym jako dom). I właśnie z połączenia informacji z telefonu zapisywanymi do arkusza Google Sheets skorzystamy. Odpowiedni przepis IFTTT: jeśli Notification received to add row to Google Drive spreadsheet. Po kilku dniach na Dysku Google dostaniemy arkusz, w którym kolejne wiersze to kolejne zdarzenia. Teraz tylko wystarczy dobrać się do tego pliku (ciekawostka - po przekroczeniu 5000 wierszy powstaje nowy plik) i przeanalizować jego zawartość. W wydobyciu plików z Google Drive pomocny będzie pakiet R googledrive. Zatem do dzieła!

# install.packages("googledrive")
library(googledrive)

library(tidyverse)
library(lubridate)
library(readxl)
library(fs)

Co się wydarzy poniżej? Najpierw wyszukamy w Google Drive wszystkie pliki z notification w nazwie (tak skonfigurowałem applet w IFTTT). Następnie dla każdego znalezionego pliku:

  • pobierzemy go na dysk lokalny (zapisze się w formacie Excela)
  • wczytamy ten plik do tymczasowej tabelki
  • zamienimy datę z ciągu tekstowego na typ wygodny do późniejszej manipulacji
  • usuniemy duplikaty (bo z rożnych powodów pojawiają się takowe)
  • wszystkie takie tymczasowe tabeli złączymy w jedną
# pobranie listy plików z Google Drive
lista <- drive_find(pattern = "notification*") %>%
  # zostawiamy tylko te, które zaczynają się od odpowiedniego ciagu
  filter(str_sub(name, 1, 13) == "notifications")


# funkcja kopiuje plik z Google Drive lokalnie
get_file <- function(id, filename) {
  if(file_exists(paste0("notifications/notification", i, ".xlsx")))
    file_delete(paste0("notifications/notification", i, ".xlsx"))

  as_id(id) %>%
    drive_get() %>%
    drive_download(path = filename) # domyślnie plik Google Sheets będzie zapisany jako plik Excela
}


# folderek na sciagane pliki
dir_create("notifications")

# tabelka na pełne dane (z wielu plików)
dane <- tibble()

# dla wszystkich znalezionych plików
for(i in 1:nrow(lista)) {
  # kopiujemy plik lokalnie
  get_file(lista[[i, "id"]], paste0("notifications/notification", i))

  # wczytujemy dane z pliku lokalnego
  dane_tmp <- read_excel(paste0("notifications/notification", i, ".xlsx"),
                  col_names = c("Data", "Aplikacja", "Komunikat", "KomunikatFull"))

  # poprawiamy daty
  dane_tmp <- dane_tmp %>%
    mutate(Data_ok = mdy_hm(Data)) %>%
    distinct()

  # łączymy w jedna wielką tabelę
  dane <- bind_rows(dane, dane_tmp)
}


# poprawiamy datę i usuwamy niechciane aplikacje ;)
dane <- dane %>%
  mutate(Godzina = hour(Data_ok),
       Dzien_tyg = wday(Data_ok, week_start = 1)) %>%
  filter(!Aplikacja %in% removed_apps)

To tyle, jeśli chodzi o najciekawszą część tego wpisu. Reszta to już zwykłe EDA. Zacznijmy od tego jak dużo powiadomień obsługuje mój telefon każdego dnia.

dane %>%
  mutate(Data = as_date(Data_ok)) %>%
  count(Data) %>%
  ggplot() +
  geom_col(aes(Data, n), fill = "lightgreen")+
  geom_smooth(aes(Data, n))

Widzimy, że rozkład jest mniej więcej równomierny. Nie wiem skąd wynika dziura w połowie marca - być może z jakiegoś powodu dane nie zapisywały się? Jak wygląda statystyka dzienna tych powiadomień?

dane %>%
  mutate(Data = as_date(Data_ok)) %>%
  count(Data) %>%
  pull(n) %>%
  summary()

##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    22.0   111.8   147.0   148.5   183.2   300.0

Średnio prawie 150 powiadomień dziennie! To jest jakiś dramat… Na szczęście spora część z nich nie jest widoczna - pojawiają się i za chwilę znikają, nie trzeba ich nawet usuwać z paska. Zobaczmy jak wygląda torcik dla 20 aplikacji, które wysyłają najwięcej powiadomień:

dane %>%
  count(Aplikacja, sort = T) %>%
  ungroup() %>%
  mutate(rn = row_number()) %>%
  mutate(Aplikacja = if_else(rn <= 20, Aplikacja, "Inne")) %>%
  mutate(p = n/sum(n)) %>%
  group_by(Aplikacja) %>%
  summarise(p = sum(p)) %>%
  ungroup() %>%
  arrange(desc(p)) %>%
  mutate(Aplikacja = fct_inorder(sprintf("%s %.1f%%", Aplikacja, 100*p))) %>%
  ggplot() +
  geom_col(aes(1, p, fill = Aplikacja), color = "gray10") +
  coord_polar(theta = "y", direction = -1) +
  theme_void()

Wykresy kołowe są kiepskie z założenia. Jedyny powód dla którego jest tutaj wykres kołowy to… pokazanie Wam ja się go robi w ggplot (coord_polar() połączone ze słupkiem z geom_col() gdzie ważna jest jedynka dla X!). Dodanie opisów poszczególnych kawałków wykresu to droga przez mękę, dlatego dodałem wartości w legendzie. W każdym razie jedna trzecia to powiadomienia systemowe, jedna szósta to VLC. Do tego o czym są te powiadomienia jeszcze dojdziemy. W jakich godzinach aplikacje puszczają notyfikacje? Czy jest to podczas jakiejś interakcji użytkownika z telefonem czy też dzieje się cały czas?

dane %>%
  count(Godzina, Aplikacja) %>%
  ggplot() +
  geom_col(aes(Godzina, n, fill = Aplikacja), color = "gray50", show.legend = FALSE) +
  facet_wrap(~Aplikacja, scales = "free_y", ncol = 4)

Jak zwykle: to zależy. Niektóre aplikacje o czymś informują całą dobę. A inne wtedy kiedy są jakieś interakcje (na przykład w serwisach społecznościowych). Jak to wygląda dodatkowo w podziale na dni tygodnia?

dane %>%
  count(Aplikacja, Godzina, Dzien_tyg) %>%
  mutate(Dzien_tyg = factor(Dzien_tyg, levels = 1:7, labels = c("pn", "wt", "śr", "cz", "pt", "sb", "nd"))) %>%
  mutate(Dzien_tyg = fct_rev(Dzien_tyg)) %>%
  ggplot() +
  geom_tile(aes(Godzina, Dzien_tyg, fill = n), color = "gray50") +
  scale_fill_distiller(palette = "YlOrRd") +
  facet_wrap(~Aplikacja, ncol = 4) +
  theme(legend.position = "bottom")

Co tutaj mamy?

  • ACR - aplikacja odpowiedzialna za nagrywanie rozmów, co mniej więcej godzinę chce wysyłać pliki do chmury (bez sensu - powinna robić to tylko po nagraniu)
  • Chrome Beta - powiadomienia związane z pobieraniem plików ze stron (na przykład PDFy). Oczywiście wtedy, kiedy korzystam z telefonu do przeglądania sieci.
  • Dropbox - komunikat “Wstrzymano przesyłanie z aparatu” przy niskim poziomie naładowania baterii
  • ES Eksplorator plików - czasem potrzebuję coś skąś przekopiować telefonem
  • Facebook - oczywiste powiadomienia o komentarzach i tym podobnych
  • Gazeta.pl - informacje push z najważniejszymi wiadomościami
  • Gmail - powiadomienia o nowej poczcie, niżej trochę więcej o tym - skąd biorą się maile w nocy?
  • Hangouts - wiadomo; widać że z komunikatora korzystam (tutaj: dostaję wiadomości, wysłanych nie ma w powiadomieniach) w ciągu dnia
  • Instagram - prawie nie używam, co widać :)
  • Interfejs - to ciekawa kategoria, niżej wyjaśnienie i szczegóły
  • JuiceSSH - najlepszy wg mnie klient SSH na telefon, pokazuje w powiadomieniu z jakim serwerem jest połączony (trochę czasem przez shella trzeba zrobi na serwerku)
  • Kalendarz - nie mam synchronizacji z korpo-kalendarzem, stąd mało powiadomień
  • LinkedIn - standardowe powiadomienia o komentarzach, polubieniach i zaproszeniach do znajomych
  • Listonic - lista zakupów, najczęściej powiadomienia o tym, że żona coś do niej dodała ;) Najczęściej w sobotę przed około-południowymi zakupami
  • Mapy - powiadomienia podczas nawigacji - wygląda na to, że najwięcej podróżuję z nawigacją w weekendy. W tygodniu chodzi głównie o korki
  • mBank - powiadomienia z aplikacji o przelewach i płatnościach kartą (widać kiedy płacę)
  • Menedżer pobierania - update’y z Google Play
  • Menedżer stron - aplikacja do obsługi fanpage’a Dane i Analizy - powiadomienia o komentarzach
  • Messenger - facebookowy komunikator, z którego nie korzystam za wiele
  • OneDrive - co kilkanaście minut pisze, że “Trwa przygotowanie…” nie wiadomo czego i do czego
  • Reddit - prawie nie udzielam się, prawie nie mam powiadomień
  • Sklep Google Play - informacje o aktualizacjach aplikacji (po co dublowane w Menedżerze Pobierania?)
  • Spotify - wiadomo - aktualnie grany utwór, muzyki słucham głównie w weekendy lub popołudniami korzystając z Chromecasta
  • System Android - działa całą dobę, ale w ciągu dnia bardziej - dlaczego? Będzie niżej.
  • Telefon - informacje o połączeniach
  • TrueCaller - raz na dobę (lub częściej) pokazuje coś w stylu “Caller ID is active” - po co? A aplikacja znakomita do rozpoznawania spamu telemarketingowego
  • Twitter - wiadomo
  • Usługi Google Play - głównie “Urządzenie w sieci Wi-Fi przesyła multimedia” przy okazji streamingu do Chromecasta z Spotify lub YouTube
  • VLC - odtwarzacz wideo (od co najmniej pół roku niczego nie oglądałem w ten sposób…), aplikacja skanuje media na telefonie i dodaje je do biblioteki. Przy okazji przygotowania tej analizy po prostu to wyłączyłem
  • Wiadomości - SMSy, będzie niżej o tym kto je śle.
  • Zarządzanie połączeniami - informacje o nieodebranych połączeniach (dlaczego nie w Telefon?)
  • Zegar - budzik; korzystam z Zegarka od Google, jak widać powiadomienie włącza się 2 godziny przed budzikiem (i z tego poziomu daje możliwość wyłączenia budzika - zwykle wyłączam go zanim zadzwoni, co widać po odcieniach z godziny 5 i 7 rano)

Przejdźmy do analizy kilku aplikacji. Kto pisze tyle maili? I przede wszystkim kto robi to w nocy?

dane %>%
  filter(Aplikacja == "Gmail") %>%
  count(Komunikat, Godzina) %>%
  filter(n >= 7) %>% # tylko nadawcy, którzy wysłali więcej niż 7 maili o tej samej godzinie
  ggplot() +
  geom_tile(aes(Godzina, Komunikat, fill = n), color = "gray50") +
  scale_fill_distiller(palette = "YlOrRd") +
  theme(legend.position = "bottom")

Jak widać główniej jest to mailing. Powiadomienia z Pracuj.pl zostały z dawnych czasów, ostatnio je wyłączyłem. Ale to głównie one przychodziły nocą. Normalne maile przychodzą w ciągu normalnego dnia. Zobaczmy najczęstsze komunikaty z poszczególnych aplikacji

dane %>%
  filter(Aplikacja %in% c("System Android", "VLC", "Sklep Google Play", "Menedżer pobierania", "ACR", "Facebook", "mBank")) %>%
  count(Aplikacja, Komunikat) %>%
  group_by(Aplikacja) %>%
  filter(n >= mean(n) + sd(n)) %>% # ot takie sitko
  ungroup() %>%
  arrange(Aplikacja, desc(n))
AplikacjaKomunikatn
FacebookFacebook277
mBankNowa operacja kartą122
Menedżer pobieraniaFacebook16
Menedżer pobieraniaMapy16
Menedżer pobieraniaTwitter15
Menedżer pobieraniaIFTTT13
Menedżer pobieraniaChrome Beta12
Menedżer pobieraniaInstagram12
Menedżer pobieraniaMessenger12
Menedżer pobieraniaGoogle Play11
Menedżer pobieraniaLinkedIn11
Menedżer pobieraniaSmart AudioBook Player11
Menedżer pobieraniaYouTube11
Menedżer pobieraniaGoogle Duo10
Menedżer pobieraniaSpotify Music10
Menedżer pobieraniaSwiftKey Beta10
Menedżer pobieraniaTruecaller - ID dzwoniącego10
Menedżer pobieraniaGoogle+9
Menedżer pobieraniaReddit: Top News, Trending Memes & Crypto Updates9
Menedżer pobieraniaZdjęcia Google9
Sklep Google PlayZaktualizowano 1 aplikację79
Sklep Google PlayNie można zaktualizować aplikacji69
Sklep Google PlayZaktualizowano 1 aplikację52
System AndroidZmień klawiaturę2245
System AndroidAplikacja Mi Band Tools działa w tle1699

Widzimy tutaj które aplikacje (ich nazwa znajduje się w kolumnie Komunikat) są często aktualizowane (Menedżer pobierania w kolumnie Aplikacja). To dane z 90 dni - wynikałoby z tego, że np. Facebook był aktualizowany mniej więcej co tydzień. Skąd biorą się powiadomienia z aplikacji System Android?

dane %>%
  filter(Aplikacja == "System Android") %>%
  group_by(Komunikat) %>%
  mutate(n = n()) %>%
  ungroup() %>%
  filter(n >= 1000) %>%
  mutate(Data = as_date(Data_ok)) %>%
  count(Data, Godzina, Komunikat) %>%
  ggplot() +
  geom_tile(aes(Data, Godzina, fill = nn), color = "gray30") +
  scale_fill_distiller(palette = "YlOrRd") +
  scale_y_reverse() +
  facet_wrap(~Komunikat) +
  theme(legend.position = "bottom")

Używam opaski Mi Band 2, stąd powiadomienie Aplikacja Mi Band Tools działa w tle. Ale same powiadomienia z aktywnością fizyczną (z Mi Fit, Stravy czy googlowego Fit) wyciąłem z danych tutaj publikowanych. Pokazuję dużo, ale nie przesadzajmy! Poza tym niewiele ciekawego wnosiły. Mamy też rozwiązanie zagadki zwiększonej liczby powiadomień systemowych w ciągu dnia. Normalnie co godzinę (czy jakoś podobnie) system informuje o współpracy z Mi Band Tools, a podczas pisania - proponuje zmianę klawiatury. Od kogo przychodzą SMSy i kiedy? Znowu - wybieram tylko najpopularniejsze:

dane %>%
  filter(Aplikacja == "Wiadomości") %>%
  group_by(Komunikat) %>%
  mutate(n = n()) %>%
  ungroup() %>%
  filter(n > 5) %>%
  count(Godzina, Komunikat) %>%
  ggplot() +
  geom_col(aes(Godzina, nn, fill = Komunikat), show.legend = FALSE) +
  facet_wrap(~Komunikat, ncol = 1)

Wyjaśnienie jest proste:

  • mBank to potwierdzenia przelewów (pamiętajcie że to suma z 3 miesięcy)
  • Orange to reklamy i komunikaty sieci
  • PlayFinanse to powiadomienia o fakturach (wystawionych lub opłaconych)

A że zmieniam operatora stąd własnie Play i Orange. Co to jest za aplikacja Interfejs i… kiedy rozładowuje się mój telefon? Informacja o stopniu naładowania baterii poniżej 15% pochodzi właśnie z aplikacji Interfejs. Zobaczmy w jakich godzinach pojawiają się kolejne komunikaty:

dane %>%
  filter(Aplikacja == "Interfejs", Komunikat == "Niski poziom baterii") %>%
  count(Godzina, KomunikatFull) %>%
  mutate(KomunikatFull = gsub("Pozostało |%", "", KomunikatFull) %>% as.numeric()) %>%
  arrange(KomunikatFull) %>%
  mutate(KomunikatFull = sprintf("Pozostało %d%%", KomunikatFull)) %>%
  mutate(KomunikatFull = fct_inorder(KomunikatFull)) %>%
  ggplot(aes(Godzina, KomunikatFull, fill = n)) +
  geom_tile(color = "gray30") +
  scale_fill_distiller(palette = "YlOrRd") +
  theme(legend.position = "bottom")

Zazwyczaj telefon wpinam do ładowarki wieczorem. Co da się zapewne wywnioskować z powyższego wykresu. To tylko przykład na wykorzystanie danych zapisanych w arkuszach Google. A także sposób na pozyskanie interesujących nas danych do dalszej pracy. Najlepiej znamy dane o sobie - wiemy na przykład do kogo piszemy SMSy, a za pomocą IFTTT możemy zapisywać treść wszystkich (przychodzących i wychodzących) do arkusza. Dzięki zgromadzonym takim sposobem danym możemy przeprowadzić samodzielnie analizę (do lub od kogo, w jakich porach, jakich słów używając) treści tych SMSów. To świetna szkoła, bo wynik analiz jest z grubsza znany - trzeba tylko znaleźć metodę dojścia do niego.