Twórz kafelki z treścią, która zmienia się z upływem czasu.
Praca z osiami czasu
Oś czasu składa się z co najmniej 1 instancji [TimelineEntry
][1], z których każda zawiera układ wyświetlany w określonym przedziale czasu. Wszystkie kafelki wymagają osi czasu.
Kafelki z jednym wejściem
Często kafelek można opisać za pomocą jednego elementu TimelineEntry
. Układ jest stały i zmieniają się tylko zawarte w nim informacje. Na przykład kafelek pokazujący Twoje postępy w aktywności fizycznej w danym dniu zawsze przedstawia ten sam układ postępów, ale możesz go dostosować tak, aby wyświetlały różne wartości. W takich przypadkach nie wiadomo z wyprzedzeniem, kiedy treść może ulec zmianie.
Zobacz ten przykład kafelka z pojedynczym elementem TimelineEntry
:
Kotlin
override fun onTileRequest( requestParams: TileRequest ): ListenableFuture<Tile> { val tile = Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) // We add a single timeline entry when our layout is fixed, and // we don't know in advance when its contents might change. .setTileTimeline( Timeline.fromLayoutElement(...) ).build() return Futures.immediateFuture(tile) }
Java
@Override protected ListenableFuture<Tile> onTileRequest( @NonNull TileRequest requestParams ) { Tile tile = new Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) // We add a single timeline entry when our layout is fixed, and // we don't know in advance when its contents might change. .setTileTimeline( Timeline.fromLayoutElement(...) ).build(); return Futures.immediateFuture(tile); }
Wpisy na osi czasu ograniczone czasowo
TimelineEntry
może opcjonalnie zdefiniować okres ważności, co pozwala kafelkowi zmieniać układ w znanym czasie bez konieczności przekazywania przez aplikację nowego kafelka.
Przykładem kanonicznym jest kafelek planu spotkania, którego oś czasu zawiera listę nadchodzących zdarzeń. Każde nadchodzące wydarzenie ma okres ważności, który określa, kiedy ma się wyświetlać.
Interfejs API kafelków umożliwia nakładanie się okresów ważności, przy czym wyświetlany jest ekran o najkrótszym czasie trwania. Wyświetlane jest tylko 1 zdarzenie naraz.
Deweloperzy mogą podać domyślny wpis kreacji zastępczej. Na przykład kafelek planu spotkania może mieć kafelek z nieskończonym okresem ważności, który jest używany, jeśli żadne inne wpisy na osi czasu nie są prawidłowe, tak jak w tym przykładowym kodzie:
Kotlin
public override fun onTileRequest( requestParams: TileRequest ): ListenableFuture<Tile> { val timeline = Timeline.Builder() // Add fallback "no meetings" entry // Use the version of TimelineEntry that's in androidx.wear.protolayout. timeline.addTimelineEntry(TimelineEntry.Builder() .setLayout(getNoMeetingsLayout()) .build() ) // Retrieve a list of scheduled meetings val meetings = MeetingsRepo.getMeetings() // Add a timeline entry for each meeting meetings.forEach { meeting -> timeline.addTimelineEntry(TimelineEntry.Builder() .setLayout(getMeetingLayout(meeting)) .setValidity( // The tile should disappear when the meeting begins // Use the version of TimeInterval that's in // androidx.wear.protolayout. TimeInterval.Builder() .setEndMillis(meeting.dateTimeMillis).build() ).build() ) } val tile = Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) .setTileTimeline(timeline.build()) .build() return Futures.immediateFuture(tile) }
Java
@Override protected ListenableFuture<Tile> onTileRequest( @NonNull RequestBuilders.TileRequest requestParams ) { Timeline.Builder timeline = new Timeline.Builder(); // Add fallback "no meetings" entry // Use the version of TimelineEntry that's in androidx.wear.protolayout. timeline.addTimelineEntry(new TimelineEntry.Builder().setLayout(getNoMeetingsLayout()).build()); // Retrieve a list of scheduled meetings List<Meeting> meetings = MeetingsRepo.getMeetings(); // Add a timeline entry for each meeting for(Meeting meeting : meetings) { timeline.addTimelineEntry(new TimelineEntry.Builder() .setLayout(getMeetingLayout(meeting)) .setValidity( // The tile should disappear when the meeting begins // Use the version of TimeInterval that's in // androidx.wear.protolayout. new TimeInterval.builder() .setEndMillis(meeting.getDateTimeMillis()).build() ).build() ); } Tile tile = new Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) .setTileTimeline(timeline.build()) .build(); return Futures.immediateFuture(tile); }
Odświeżanie kafelka
Informacje widoczne na kafelku mogą po pewnym czasie wygasnąć. Na przykład kafelek pogody, który pokazuje tę samą temperaturę w ciągu dnia, nie jest dokładny.
Aby radzić sobie z wygasającymi danymi, ustaw przedział aktualności podczas tworzenia kafelka, który określa, jak długo kafelek jest ważny. W przykładzie kafelka pogody możesz aktualizować jego zawartość co godzinę, jak pokazano w tym przykładowym kodzie:
Kotlin
override fun onTileRequest(requestParams: RequestBuilders.TileRequest) = Futures.immediateFuture(Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) .setFreshnessIntervalMillis(60 * 60 * 1000) // 60 minutes .setTileTimeline(Timeline.fromLayoutElement( getWeatherLayout()) ).build() )
Java
@Override protected ListenableFuture<Tile> onTileRequest( @NonNull TileRequest requestParams ) { return Futures.immediateFuture(new Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) .setFreshnessIntervalMillis(60 * 60 * 1000) // 60 minutes .setTimeline(Timeline.fromLayoutElement( getWeatherLayout()) ).build()); }
Gdy ustawisz interwał aktualności, system wywoła [onTileRequest()
][2] krótko po jego zakończeniu. Jeśli nie ustawisz interwału aktualności, system nie wywoła onTileRequest()
.
Kafelek może też wygasnąć w wyniku wydarzenia zewnętrznego. Użytkownik mógł na przykład usunąć spotkanie ze swojego kalendarza, a jeśli kafelek nie został odświeżony, nadal będzie na nim widoczne to usunięte spotkanie. W takim przypadku poproś o odświeżenie z dowolnego miejsca w kodzie aplikacji, jak pokazano w tym przykładowym kodzie:
Kotlin
fun eventDeletedCallback() { TileService.getUpdater(context) .requestUpdate(MyTileService::class.java) }
Java
public void eventDeletedCallback() { TileService.getUpdater(context) .requestUpdate(MyTileService.class); }
Wybierz przepływ pracy związany z aktualizacją
Skorzystaj z tych sprawdzonych metod, aby określić sposób konfigurowania aktualizacji kafelków:
- Jeśli aktualizacja jest przewidywalna – na przykład dotyczy następnego wydarzenia w kalendarzu użytkownika – użyj osi czasu.
- Przy pobieraniu danych platformy użyj powiązania danych, aby system automatycznie aktualizował dane.
Jeśli aktualizację można przeprowadzić na urządzeniu w krótkim czasie, np. zmienić pozycję obrazu na kafelku wschodu słońca, użyj funkcji [
onTileRequest()
][2].Jest to szczególnie przydatne, gdy musisz wcześniej wygenerować wszystkie obrazy. Jeśli w przyszłości zechcesz wygenerować nowy obraz, wywołaj [
setFreshnessIntervalMillis()
][3].Jeśli wykonujesz bardziej intensywne zadania w tle, np. przeprowadzasz sondowanie w celu uzyskania danych o pogodzie, użyj funkcji [
WorkManager
][4] i prześlij aktualizacje do kafelka.Jeśli aktualizacja jest spowodowana zdarzeniem zewnętrznym – takim jak włączenie świateł, otrzymanie e-maila lub zaktualizowanie notatki – wyślij wiadomość [Komunikacja w chmurze Firebase (FCM)][5], aby ponownie aktywować aplikację, a następnie przekaż aktualizacje do kafelka.
Jeśli proces synchronizacji danych kafelków może być kosztowny, wykonaj te czynności:
- Zaplanuj synchronizację danych.
- Włącz minutnik na 1–2 sekundy.
- Jeśli otrzymasz aktualizację ze zdalnego źródła danych przed upływem czasu, pokaż zaktualizowaną wartość z synchronizacji danych. W przeciwnym razie pokazuj wartość lokalną z pamięci podręcznej.
Polecane dla Ciebie
- Uwaga: tekst linku wyświetla się, gdy JavaScript jest wyłączony
- Zminimalizuj wpływ regularnych aktualizacji
- Dostęp do lokalizacji w tle
- Pierwsze kroki z funkcją WorkManager