poniedziałek, 25 czerwca 2018

Co robi widget czyli kilka słów o onUpdate

Funkcja onUpdate:
public void onUpdate (Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
  • Context: obiekt typu Context, z którym aktualnie działa widget
  • AppWidgetManager: obiekt typu AppWidgetManager, który umożliwi wywołanie funkcji aktualizacji - AppWidgetManager.updateAppWidget(ComponentName, RemoteViews)
  • int: numery ID widgetów (jego instancji), które będą aktualizowane
Jest to najczęściej wywoływana funkcja widgetu (czasami jedyna wymagająca implementacji).

Tu definiujemy:
  • jak ma być skonfigurowany widget (jeśli nie ma specjalnej aktywności do konfiguracji)
  • co ma zrobić widget gdy wystąpi jakieś działanie użytkownika
  • jaką aktywność ma otworzyć widget (jeśli ma)
  • jak mają działać elementy wigdetu, np. przyciski (jeśli je ma)
Warto pamiętać:
  • updatePeriodMillis - update działa zgodnie z tym co zdefiniowano w pierwszej instancji widgetu (nawet jeśli druga instancja została skonfigurowana inaczej, to te ustawienia zostaną zignorowane
  • AppWidgetProvider jest rozszerzeniem BroadcastReceiver co nie daje gwarancji, że gdy metoda widgetu zakończy wykonywanie, to proces będzie nadal działał
    • w przypadku gdy wykonanie wszystkiego może potrwać dłużej zaleca się w metodzie onUpdate włączyć serwis

piątek, 22 czerwca 2018

Jak działa AppWidgetProvider czyli jakie widget otrzymuje sygnały i co się wtedy dzieje

AppWidgetProvider (zadeklarowany w Manifeście jako <receiver>) umożliwia odbieranie sygnałów przeznaczonych tylko dla widgetów z następujących metod:
  • onUpdate()
    • wywoływana automatycznie zgodnie z parametrem updatePeriodMillis
    • wywoływana automatycznie przy dodawaniu widgetu, żeby np. domyślnie skofigurować widget, jeśli trzeba uruchomić serwis
    • wywoływana z aktywności przy dodawaniu widgetu tylko wtedy, jeśli zostało tak zaprogramowane - programista musi zapewnić, że widget będzie w zupełności skonfigurowany, jeśli decyduje się sosać aktywność umożliwiającą konfigurację
  • onAppWidgetOptionsChanged()
    • wywoływana przy dodawaniu widgetu
    • wywoływana przy zmianie rozmiaru widgetu
    • umożliwia pokazanie lub schowanie elementów widgetu w zależności od jego rozmiaru
    • wprowadzona w Android 4.1 (API 16)
  • onDeleted(Context, int[])
    •  wywoływana gdy App Widget host zamyka widget - konkretną instancję, tylko jedną
  • onEnabled(Context)
    • wywoływana gdy dodawany jest pierwszy obiekt danego widgetu
    • jeśli widget może mieć więcej niż jedną instancję, przy dodawaniu drugiej metoda nie jest wywoływana
    • metoda odpowiednia do implementacji wszystkich funkcji, które mają się wykonać tylko raz, np. stworzenie bazy danych, szczególna konfiguracja
  • onDisabled(Context)
    • wywoływana gdy z App Widget host usuwana jest ostatnia instancja widgetu
    • metoda odpowiednia do implementacji funkcji, które "posprzątają" po widgecie, np. usuną czasowe bazy danych
  • onReceive(Context, Intent)
    • wywoływana przy każdym odebraniu sygnału
    • wywoływana przed każdą ze wspomnianych powyżej metod
    • nie musi być implementowana - AppWidgetProvider ma domyślną implementację, która w odpowiedni sposób radzi sobie z odbieranymi sygnałami i wywołuje odpowiednie funkcje

Wygląd widgetu - zmiana rozmiaru

Widget nie musi mieć stałego, wybranego przez nas rozmiaru - może być konfigurowany przez użytkownika.
Nie musi też mieć stałych elementów - można je dopasować do wybranego rozmiaru.
Podczas zmiany rozmiaru widgetu wywoływana jest metoda onAppWidgetOptionsChanged(). To w jej treści możemy określić które elementy będą widoczne a które nie. Żeby zorientować się jaki jest aktualny (ustawiony przez użytkownika) rozmiar trzeba wywołać metodę getAppWidgetOptions(), która zwróci w odpowiedzi obiekt typu Bundle, który zawiera:

  • OPTION_APPWIDGET_MIN_WIDTH - dolna granica szerokości w jednostkach dp
  • OPTION_APPWIDGET_MAX_WIDTH - górna granica szerokości w jednostkach dp
  • OPTION_APPWIDGET_MIN_HEIGHT - dolna granica długości w jednostkach dp
  • OPTION_APPWIDGET_MAX_HEIGHT - górna granica długości w jednostkach dp

Wygląd widgetu - podstawowy projekt

Układ widgetu bazuje na klasie RemoteViews

Tworząc układ widgetu trzeba pamiętać o:
  • sprawdzeniu, czy wybrany układ (layout) i elementy są wspierane przez RemoteViews
  • marginesach całego widgetu - widget nie powinien stykać się z krawędziami ekranu i z innymi aplikacjami (od wersji Android 4.0 (targetSdkVersion >= 14) te marginesy są ustawiane domyślnie, nie trzeba ich dodatkowo wprowadzać)
  • marginesach elementów widgetu - powinny być od siebie trochę odsunięte, żeby dało się ich używać
Ciekawym elementem układu jest stub - niewidoczny obiakt, który można w trakcie wykonywania programu zmienić na inny, powiązany.

czwartek, 21 czerwca 2018

Konfiguracja widgetu czyli metadane

Metadane określają podstawowe parametry widgetu:
  • minWidth, minHeight - minimalna, domyślna przestrzeń zajmowana przez widget
    •  widgety zajmują na ekranie pewne zdefiniowane komórki (tak samo ustawiając ikonki aplikacji na ekranie też nie możemy ich mieć gdziekolwiek), jeśli podana wartość nie będzie odpowiadała wielkości pełnych komórek, zostanie zaokrąglona w górę, tak aby zająć pełną liczbę zdefiniowanych komórek
    • minimalna wartość nie może być większa niż 4x4 komórki (żeby zachować przenoszalność widgetu na różne urządzenia)
  •  minResizeWidth, minResizeHeight - wielkość, poniżej której widget nie będzie nadawał się do użycia
    • ustawienie tych parametrów oznacza, że użytkownik będzie mógł zmienić wielkość widgetu na mniejszy niż domyślny (ale nie mniejszy niż podany w tym parametrze)
  •  updatePeriodMillis - częstotliwość z jaką widget będzie wysyłał żądanie aktualizacji (onUpdate(), AppWidgetProvider )
    • podana wartość jest tylko szacunkowa, system wykona aktualizację mniej więcej w tym czasie, jeśli będzie mógł
    • trzeba ostrożnie dobrać ten parametr, żeby nie zużywać za dużo baterii 
    • sysem wybudzi urządzenie z uśpienia gdy nadejdzie czas aktualizacji ustawiony w tym parametrze
    • żeby uniknąć budzenia urządzenia, można ustawić aktualizację opartą na alarmie "niebudzącym" urządzenia
      • korzystając z AlarmManager ustaw alarm przez Intent otrzymywany przez AppWidgetProvider
      • ustaw alarmowi typ ELAPSED_REALTIME lub RTC
      • ustaw updatePeriodMillis = 0
  • initialLayout - ścieżka do pliku określającego wygląd (layout) widgetu
  • configure - aktywność, która zostanie uruchomiona po dodaniu widgetu w celu umożliwienia użytkownikowi skonfigurowania go
  • previewImage - podgląd przykładowo skonfigurowanego widgetu dla użytkownika, dostępny dla niego gdy wybiera widgety
    • jeśli nie ma ustwionego tego parametru, jako podgląd wyświetlana będzie ikona aplikacji
  • autoAdvanceViewId - id widoku "rozszerzonego"
    • dla widgetów, które mogą być rozbudowywane (advanceable)
    • informuje host co powinno być rozbudowywane
    • host będzie wykonywał akcję advance() gdy będzie to sensowne, czyli np. tylko gdy widget będzie widoczny
  • resizeMode - określa zasady zmiany rozmiaru widgetu - horizontal, vertical, none
  • widgetCategory - określa gdzie może być wyświetlany widget - home_screen, keyguard (tylko do Android 5.0), both

środa, 20 czerwca 2018

AndroidManifest - dodajemy widget

W manifeście informujemy aplikację o składowych częściach widgetu.

(deklarujemy obiekt, który będzie mógł odbierać informacje od aplikacji i/lub systemu)
<receiver android:name="nazwa AppWidgetProvider" > 
(tu powyżej -"name"- mówimy aplikacji jak nazywa się klasa, która ma informacje jak będzie zachowywał się ten obiekt - widget)
    <intent-filter> 
(tu deklarujemy, na co widget będzie reagował, co będzie odbierał)
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> 
(jeśli widget ma być aktualizowany należy to koniecznie zadeklarować)
    </intent-filter> (tu mówimy gdzie są dane konfiguracyjne widgetu)
    <meta-data android:name="android.appwidget.provider"
               android:resource="@xml/example_appwidget_info" />
</receiver>
więcej o atrybucie <receiver>

wtorek, 19 czerwca 2018

Z czego składa się widget?

  • AppWidgetProviderInfo - plik XML zawierający metadane naszego widgetu
    • metadane -  dane o danych – ustrukturalizowane informacje stosowane do opisu zasobów informacji lub obiektów informacji, dostarczające szczegółowych danych, dotyczących atrybutów zasobów lub obiektów informacji, w celu ułatwienia ich znalezienia, identyfikacji, a także zarządzania tymi zasobami
  • AppWidgetProvider (implementacja) - zdefiniownie tego jak widget będzie się zachowywał pod wpływem różnych działań
  • View layout - plik XML opisujący wygląd widgetu
  • App Widget configuration Activity (opcjonalnie) - sktywność, która otworzy się w momencie dodawania widgetu i umożliwi ustawienie konfiguracji
  • zmiana w AndroidManifest.xml - deklaracja atrybutu <receiver> o takiej nazwie jaką ma dodany wcześniej AppWidgetProviderInfo

poniedziałek, 18 czerwca 2018

Co to jest widget?

To taka miniaturka aplikacji - np. większość telefonów ma na Home Screen ustawiony zegar.
Widget:
  • może być osadzony w innych aplikacjach (taka aplikacja to App Widget Host i jest nią np. home screen),
  • cyklicznie się aktualizuje,
  • jest wyświetlany dzięki App Widget Provider.