Показывать периодические обновления на плитках

Создавайте плитки с содержимым, которое меняется со временем.

Работа с временными рамками

Временная шкала состоит из одного или нескольких экземпляров TimelineEntry , каждый из которых содержит макет, отображаемый в течение определенного временного интервала. Для всех плиток необходима временная шкала.

Диаграмма временной шкалы плиток

Плитка с одним входом

Часто плитку можно описать с помощью одного элемента TimelineEntry . Макет фиксирован, и изменяется только информация внутри него. Например, плитка, отображающая ваш прогресс в фитнесе за день, всегда показывает один и тот же макет прогресса, хотя вы можете изменить этот макет, чтобы отображать другие значения. В таких случаях вы заранее не знаете, когда содержимое может измениться.

См. следующий пример плитки с одной TimelineEntry :

override fun onTileRequest(
    requestParams: RequestBuilders.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(simpleLayout(this)))
            .build()
    return Futures.immediateFuture(tile)
}

Записи в хронологической шкале, привязанные ко времени

В элементе TimelineEntry можно дополнительно задать период действия, позволяющий изменять расположение плитки в известное время без необходимости добавления новой плитки в приложение.

Типичным примером является элемент повестки дня, временная шкала которого содержит список предстоящих событий. Каждое предстоящее событие имеет период действия, указывающий, когда его следует отобразить.

API для работы с тайлами позволяет использовать перекрывающиеся периоды действия, при этом отображается экран с наименьшим оставшимся временем. Одновременно отображается только одно событие.

Разработчики могут указать резервный вариант по умолчанию. Например, в элементе повестки дня может быть элемент с неограниченным сроком действия, который используется, если ни один другой вариант временной шкалы недействителен, как показано в следующем примере кода:

override fun onTileRequest(
    requestParams: RequestBuilders.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(
        TimelineBuilders.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(
            TimelineBuilders.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.
                    TimelineBuilders.TimeInterval.Builder()
                        .setEndMillis(meeting.dateTimeMillis)
                        .build()
                )
                .build()
        )
    }

    val tile =
        Tile.Builder()
            .setResourcesVersion(RESOURCES_VERSION)
            .setTileTimeline(timeline.build())
            .build()
    return Futures.immediateFuture(tile)
}

Обновить плитку

Информация, отображаемая на плитке, может устареть через некоторое время. Например, плитка с погодой, показывающая одинаковую температуру в течение дня, не является точной.

Для обработки устаревающих данных установите интервал актуальности при создании плитки, который определяет, как долго плитка будет действительна. В примере с плиткой погоды вы можете обновлять ее содержимое каждый час, как показано в следующем примере кода:

override fun onTileRequest(
    requestParams: RequestBuilders.TileRequest
): ListenableFuture<Tile?> =
    Futures.immediateFuture(
        Tile.Builder()
            .setResourcesVersion(RESOURCES_VERSION)
            .setFreshnessIntervalMillis(60 * 60 * 1000) // 60 minutes
            .setTileTimeline(Timeline.fromLayoutElement(getWeatherLayout()))
            .build()
    )

Если вы задаёте интервал обновления, система вызывает onTileRequest() вскоре после окончания этого интервала. Если вы не задаёте интервал обновления, система не вызывает onTileRequest() .

Плитка также может перестать отображаться из-за внешнего события. Например, пользователь может удалить встречу из своего календаря, и если плитка не будет обновлена, она по-прежнему будет отображать удаленную встречу. В этом случае запросите обновление из любого места в коде вашего приложения, как показано в следующем примере кода:

fun eventDeletedCallback() {
     TileService.getUpdater(context)
             .requestUpdate(MyTileService::class.java)
}

Выберите рабочий процесс обновления

Используйте эти рекомендации, чтобы определить, как настроить обновление тайлов:

  • Если обновление предсказуемо — например, если оно связано со следующим событием в календаре пользователя — используйте временную шкалу.
  • При получении данных с платформы используйте привязку данных, чтобы система автоматически обновляла данные.
  • Если обновление можно рассчитать на устройстве за короткое время — например, обновить положение изображения на тайле восхода солнца — используйте onTileRequest() .

    Это особенно полезно, когда необходимо сгенерировать все изображения заранее. Если вам потребуется сгенерировать новое изображение позже, вызовите setFreshnessIntervalMillis() .

  • Если вы выполняете ресурсоемкие фоновые задачи многократно, например, запрашиваете данные о погоде, используйте WorkManager и отправляйте обновления на свой тайл.

  • Если обновление происходит в ответ на внешнее событие — например, включение света, получение электронного письма или обновление заметки — отправьте сообщение Firebase Cloud Messaging (FCM) , чтобы снова активировать приложение, а затем отправьте обновления на плитку.

  • Если процесс синхронизации данных тайлов может оказаться дорогостоящим, выполните следующие действия:

    1. Запланируйте синхронизацию данных.
    2. Запустите таймер на 1-2 секунды.
    3. Если вы получили обновление из удаленного источника данных до истечения времени, отобразите обновленное значение из синхронизации данных. В противном случае отобразите кэшированное локальное значение.
{% verbatim %} {% endverbatim %} {% verbatim %} {% endverbatim %}