Las fuentes de datos de complicaciones exponen información a las complicaciones de caras de reloj y proporcionan texto, imágenes y números que la cara de reloj puede renderizar.
Un servicio de fuente de datos extiende
SuspendingComplicationDataSourceService
para proporcionar información útil directamente a una cara de reloj.
Cómo comenzar
Agrega la siguiente dependencia al módulo de tu app:
dependencies { implementiation("androidx.wear.watchface:watchface-complications-data-source-ktx:1.2.1") }
Crea el servicio de fuente de datos
Cuando se necesitan datos de complicaciones, el sistema Wear OS envía solicitudes de actualización a tu fuente de datos.
Para responder a las solicitudes de actualización, tu fuente de datos debe implementar el método
onComplicationRequest()
de la clase SuspendingComplicationDataSourceService
.
El sistema Wear OS llama a onComplicationRequest()
cuando necesita datos de tu fuente (por ejemplo, cuando se activa una complicación que usa tu fuente de datos o cuando transcurre un período de tiempo fijo).
Nota: Cuando la fuente de datos proporciona información, la cara de reloj recibe los valores sin procesar. La cara del reloj es responsable de formatear los datos para mostrarlos.
En el siguiente fragmento de código, se muestra un ejemplo de implementación:
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() // ... }
Permisos y declaraciones de manifiesto
Las fuentes de datos deben incluir declaraciones específicas en sus manifiestos para que el sistema Android las reconozca como fuentes de datos. En esta sección, se explican los parámetros de configuración necesarios para las fuentes de datos.
En el manifiesto de tu app, declara el servicio y agrega un filtro de intents para la acción de solicitud de actualización.
El manifiesto también debe proteger el servicio. Para ello, debe agregar el permiso BIND_COMPLICATION_PROVIDER
para garantizar que solo el sistema Wear OS pueda vincularse a servicios de proveedores.
Además, incluye un atributo android:icon
en el elemento service
que proporciona un ícono blanco de un solo color. Recomendamos el uso de elementos de diseño vectoriales para los íconos.
El ícono representa la fuente de datos y se muestra en el selector de complicaciones.
Por ejemplo:
<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 e.g. 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, the complication can be configured by the user by specifying a configuration activity. --> <meta-data android:name="android.support.wearable.complications.PROVIDER_CONFIG_ACTION" android:value="MY_CONFIG_ACTION" /> </service>
Elementos de metadatos
En tu archivo de manifiesto, observa los siguientes elementos de metadatos:
-
android:name="android.support.wearable.complications.SUPPORTED_TYPES"
: Especifica los tipos de datos de complicaciones que admite la fuente de datos. -
android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS"
: Especifica la frecuencia con la que el sistema debe buscar actualizaciones de los datos.
Cuando está activa tu fuente de datos de complicación, UPDATE_PERIOD_SECONDS
especifica la frecuencia con la que quieres que el sistema compruebe la disponibilidad de actualizaciones de los datos. Si no es necesario que la información que se muestra en la complicación se actualice de forma regular, como cuando usas actualizaciones push, establece ese valor en 0
.
Si no configuras UPDATE_PERIOD_SECONDS
como 0
, debes usar un valor de al menos 300
(5 minutos), que es el período mínimo de actualización que aplica el sistema, para preservar la duración de batería del dispositivo. Además, ten en cuenta que las solicitudes de actualización son menos frecuentes cuando no se lleva puesto el dispositivo o cuando se encuentra en el modo ambiente.
Agrega una actividad de configuración
Si es necesario, una fuente de datos puede incluir una actividad de configuración que se muestra al usuario cuando este último elige esa fuente de datos en particular en el selector de complicaciones. Por ejemplo, una fuente de datos de reloj mundial podría tener una actividad de configuración que permita al usuario elegir la ciudad o la zona horaria que se mostrará.
El manifiesto de ejemplo incluye un elemento meta-data
con la clave PROVIDER_CONFIG_ACTION
. El valor de este elemento es la acción que se usa para iniciar la actividad de configuración.
Crea la actividad de configuración y agrega un filtro de intents que coincida con la acción en tu archivo de manifiesto.
<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>
La actividad puede obtener detalles de la ranura de la complicación que está configurando desde el intent dentro del método onCreate()
de la actividad:
// 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)
La actividad de configuración debe encontrarse en el mismo paquete que el proveedor. Además, debe mostrar RESULT_OK
o RESULT_CANCELED
para indicar al sistema si se debe establecer la fuente de datos:
setResult(RESULT_OK) // Or RESULT_CANCELED to cancel configuration finish()
Usa actualizaciones push
Como alternativa a especificar un intervalo de actualización en el manifiesto de tu app, puedes usar una instancia de
ComplicationDataSourceUpdateRequester
para iniciar actualizaciones de manera dinámica.
Para solicitar una actualización, llama a requestUpdate()
.
Precaución: Para preservar la duración de batería del dispositivo, no llames a requestUpdate()
desde tu instancia de ComplicationDataSourceUpdateRequester
con más frecuencia que un promedio de 5 minutos.
Proporciona valores dependientes del tiempo
Algunas complicaciones necesitan mostrar un valor que se relacione con la hora actual. Entre algunos ejemplos, se incluyen la fecha actual, el tiempo hasta la próxima reunión o la hora en otra zona horaria.
No actualices una complicación cada segundo o minuto para mantener esos valores actualizados. En cambio, especifica los valores como relativos a la fecha o la hora actual a través de texto dependiente del tiempo. Las siguientes clases te permiten crear estos valores dependientes del tiempo:
-
TimeFormatComplicationText
: Da formato a un valor de fecha o hora. -
TimeDifferenceComplicationText
: Cuenta hacia arriba o hacia abajo hasta un momento específico.
Datos de Rutas
Para las fuentes de datos de la complicación que proporcionan una secuencia de valores en momentos predefinidos, usa SuspendingTimelineComplicationDataSourceService
.
Un ejemplo de esto sería una fuente de datos de "próximo evento" de una app de calendario: En lugar de que el sistema tenga que sondear la fuente de datos con regularidad para obtener el próximo evento, la fuente de datos puede proporcionar una línea de tiempo de eventos una vez, y luego la fuente de datos puede iniciar actualizaciones si cambia el calendario. Esto minimiza la carga en el sistema y permite que la complicación muestre el evento correcto de manera oportuna:
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() // ... }
El comportamiento de SuspendingTimelineComplicationDataSourceService
es el siguiente:
- Cuando la hora actual se encuentra dentro de la hora de inicio y la hora de finalización de una entrada en la línea de tiempo, la cara del reloj usa ese valor.
- Cuando la hora actual no coincide con ninguna entrada de la línea de tiempo, se usa el valor predeterminado. Por ejemplo, en la app de calendario, podría ser "Sin evento".
- Si la hora actual coincide con varios eventos, se usa el evento más corto.
Proporciona valores dinámicos
A partir de Wear OS 4, algunas complicaciones pueden mostrar valores que se actualizan con más frecuencia según los valores disponibles directamente en la plataforma. Para proporcionar esta capacidad en tus complicaciones, usa campos
ComplicationData
que acepten valores dinámicos. La plataforma evalúa y actualiza estos valores con frecuencia, sin necesidad de que el proveedor de complicaciones esté en ejecución.
Entre los campos de ejemplo, se incluyen el
campo de valor dinámico de GoalProgressComplicationData
y
DynamicComplicationText
, que se puede usar en cualquier campo
ComplicationText
. Estos valores dinámicos se basan en la biblioteca
androidx.wear.protolayout.expression
.
En ciertas situaciones, la plataforma no puede evaluar valores dinámicos:
- A veces, el valor dinámico no está disponible: Esto sucede, por ejemplo, cuando el dispositivo está lejos de la muñeca. En estas situaciones, la plataforma usa el valor del
campo de resguardo de invalidación de valor dinámico en el
campo de marcador de posición de
NoDataComplicationData
. - El valor dinámico nunca está disponible: Esto sucede en un dispositivo que ejecuta una versión anterior de Wear OS 4. En esta situación, la plataforma usa un campo de resguardo complementario, como
getFallbackValue()
.