Подвергайте данные осложнениям

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

Служба источника данных расширяет SuspendingComplicationDataSourceService для доставки полезной информации непосредственно на циферблат часов.

Начиная

Добавьте следующую зависимость в модуль вашего приложения:

dependencies {
  implementiation("androidx.wear.watchface:watchface-complications-data-source-ktx:1.2.1")
}

Создать службу источника данных

Когда требуются данные о дополнениях, система Wear OS отправляет запросы на обновление в ваш источник данных. Для ответа на эти запросы ваш источник данных должен реализовать метод onComplicationRequest() класса SuspendingComplicationDataSourceService .

Система Wear OS вызывает onComplicationRequest() , когда ей требуются данные из вашего источника, например, когда становится активным расширение, использующее ваш источник данных, или по истечении фиксированного периода времени.

Примечание: Когда источник данных предоставляет данные, циферблат получает необработанные значения. Циферблат отвечает за форматирование данных для отображения.

В следующем фрагменте кода показан пример реализации:

class MyComplicationDataSourceService : SuspendingComplicationDataSourceService() {
    override suspend fun onComplicationRequest(request: ComplicationRequest): ComplicationData? {
        // Retrieve the latest info for inclusion in the data.
        val text = getLatestData()
        return shortTextComplicationData(text)
    }

    override fun getPreviewData(type: ComplicationType): ComplicationData? {
        return shortTextComplicationData("Event 1")
    }

    private fun shortTextComplicationData(text: String) =
        ShortTextComplicationData.Builder(
            text = PlainComplicationText.Builder(text).build(),
            contentDescription = PlainComplicationText.Builder(text).build()
        )
            // Add further optional details here such as icon, tap action, and title.
            .build()

    // ...
}

Манифест деклараций и разрешений

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

В манифесте приложения объявите службу и добавьте фильтр намерений для действия запроса на обновление. Манифест также должен защитить службу, добавив разрешение BIND_COMPLICATION_PROVIDER , чтобы гарантировать, что только система Wear OS сможет подключаться к службам поставщика.

Также добавьте атрибут android:icon в элемент service , который предоставляет одноцветный белый значок. Мы рекомендуем использовать векторные изображения для значков. Значок представляет источник данных и отображается в окне выбора дополнений.

Вот пример:

<service
    android:name=".snippets.complication.MyComplicationDataSourceService"
    android:exported="true"
    android:label="@string/my_complication_service_label"
    android:icon="@drawable/complication_icon"
    android:permission="com.google.android.wearable.permission.BIND_COMPLICATION_PROVIDER">
    <intent-filter>
        <action android:name="android.support.wearable.complications.ACTION_COMPLICATION_UPDATE_REQUEST" />
    </intent-filter>

    <!-- Supported types should be comma-separated, for example: "SHORT_TEXT,SMALL_IMAGE" -->
    <meta-data
        android:name="android.support.wearable.complications.SUPPORTED_TYPES"
        android:value="SHORT_TEXT" />
    <meta-data
        android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS"
        android:value="300" />

    <!-- Optionally, specify a configuration activity, where the user can configure your complication. -->
    <meta-data
        android:name="android.support.wearable.complications.PROVIDER_CONFIG_ACTION"
        android:value="MY_CONFIG_ACTION" />

</service>

Элементы метаданных

В файле манифеста обратите внимание на следующие элементы метаданных:

  • android:name="android.support.wearable.complications.SUPPORTED_TYPES" : указывает типы данных о сложностях, которые поддерживает источник данных.
  • android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS" : указывает, как часто система должна проверять наличие обновлений данных.

Когда источник данных расширения активен, UPDATE_PERIOD_SECONDS определяет частоту проверки системой наличия обновлений данных. Если информация, отображаемая в дополнении, не требует регулярного обновления, например, при использовании push-обновлений , установите это значение равным 0 .

Если вы не установите значение UPDATE_PERIOD_SECONDS равным 0 , необходимо использовать значение не менее 300 (5 минут) — это минимальный период обновления, устанавливаемый системой, для экономии заряда батареи устройства. Кроме того, имейте в виду, что запросы на обновление поступают реже, когда устройство находится в режиме ожидания или не надето на руку.

Добавить действие конфигурации

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

Пример манифеста включает элемент meta-data с ключом PROVIDER_CONFIG_ACTION . Значение этого элемента — действие, используемое для запуска конфигурационного задания.

Создайте действие конфигурации и добавьте фильтр намерений, который соответствует действию для него в вашем файле манифеста.

<intent-filter>
    <action android:name="MY_CONFIG_ACTION" />
    <category android:name="android.support.wearable.complications.category.PROVIDER_CONFIG" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

Действие может получить сведения о слоте усложнения, который оно настраивает, из намерения в методе onCreate() действия:

// Keys defined on ComplicationDataSourceService
val id = intent.getIntExtra(EXTRA_CONFIG_COMPLICATION_ID, -1)
val type = intent.getIntExtra(EXTRA_CONFIG_COMPLICATION_TYPE, -1)
val source = intent.getStringExtra(EXTRA_CONFIG_DATA_SOURCE_COMPONENT)

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

setResult(RESULT_OK) // Or RESULT_CANCELED to cancel configuration
finish()

Используйте push-обновления

В качестве альтернативы указанию интервала обновления в манифесте приложения вы можете использовать экземпляр ComplicationDataSourceUpdateRequester для динамического инициирования обновлений. Чтобы запросить обновление, вызовите requestUpdate() .

Внимание: Чтобы продлить срок службы батареи устройства, не вызывайте requestUpdate() из экземпляра ComplicationDataSourceUpdateRequester чаще, чем каждые 5 минут в среднем.

Предоставлять значения, зависящие от времени

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

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

Данные временной шкалы

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

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

class MyTimelineComplicationDataSourceService : SuspendingTimelineComplicationDataSourceService() {
    override suspend fun onComplicationRequest(request: ComplicationRequest): ComplicationDataTimeline? {
        if (request.complicationType != ComplicationType.SHORT_TEXT) {
            return ComplicationDataTimeline(
                defaultComplicationData = NoDataComplicationData(),
                timelineEntries = emptyList()
            )
        }
        // Retrieve list of events from your own datasource / database.
        val events = getCalendarEvents()
        return ComplicationDataTimeline(
            defaultComplicationData = shortTextComplicationData("No event"),
            timelineEntries = events.map {
                TimelineEntry(
                    validity = TimeInterval(it.start, it.end),
                    complicationData = shortTextComplicationData(it.name)
                )
            }
        )
    }

    override fun getPreviewData(type: ComplicationType): ComplicationData? {
        return shortTextComplicationData("Event 1")
    }

    private fun shortTextComplicationData(text: String) =
        ShortTextComplicationData.Builder(
            text = PlainComplicationText.Builder(text).build(),
            contentDescription = PlainComplicationText.Builder(text).build()
        )
            // Add further optional details here such as icon, tap action, title etc
            .build()

    // ...
}

Поведение SuspendingTimelineComplicationDataSourceService выглядит следующим образом:

  • Если текущее время попадает в интервал между начальным и конечным временем записи на временной шкале, циферблат использует это значение.
  • Если текущее время не попадает ни в одну запись на временной шкале, используется значение по умолчанию. Например, в приложении «Календарь» это может быть «Нет событий».
  • Если текущее время попадает в несколько событий, используется самое короткое событие.

Предоставлять динамические значения

Начиная с Wear OS 4, некоторые расширения могут отображать значения, обновляемые чаще, на основе данных, доступных непосредственно платформе. Чтобы реализовать эту возможность в своих расширениях, используйте поля ComplicationData , принимающие динамические значения . Платформа часто оценивает и обновляет эти значения, не требуя запуска поставщика расширений.

Примерами полей являются динамическое значение GoalProgressComplicationData и DynamicComplicationText , которое можно использовать в любом поле ComplicationText . Эти динамические значения основаны на библиотеке androidx.wear.protolayout.expression .

В определенных ситуациях платформа не может оценивать динамические значения: