Источники данных о дополнениях предоставляют информацию для дополнений на циферблате, предоставляя текст, изображения и цифры, которые может отображать циферблат.
Служба источника данных расширяет 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 минут в среднем.
Предоставлять значения, зависящие от времени
В некоторых усложнениях необходимо отображать значение, связанное с текущим временем. Например, текущую дату, время до следующей встречи или время в другом часовом поясе.
Не обновляйте расширение каждую секунду или минуту, чтобы поддерживать эти значения в актуальном состоянии. Вместо этого указывайте значения относительно текущей даты или времени, используя текст, зависящий от времени. Следующие классы позволяют создавать такие значения, зависящие от времени:
-
TimeFormatComplicationText
— форматирует значение даты или времени. -
TimeDifferenceComplicationText
— отсчет времени до указанного времени.
Данные временной шкалы
Для источников данных усложнения, которые предоставляют последовательность значений в заранее определенные моменты времени, используйте 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
.
В определенных ситуациях платформа не может оценивать динамические значения:
- Динамическое значение иногда недоступно: например, когда устройство снято с запястья. В таких ситуациях платформа использует значение резервного поля аннулирования динамического значения в поле-заполнителе
NoDataComplicationData
. - Динамическое значение никогда не доступно: это происходит на устройстве, работающем на более старой версии Wear OS 4. В этой ситуации платформа использует сопутствующее резервное поле, например
getFallbackValue ()
.