Un DataItem
define la interfaz que usa el sistema para sincronizar datos entre dispositivos portátiles y wearables. En general, un DataItem
tiene los siguientes componentes:
- Carga útil: Un array de bytes que puedes configurar con los datos, lo que te permite realizar tu propia serialización o deserialización de objetos. El tamaño de la carga útil está limitado a 100 KB.
-
Ruta de acceso: Una string única que debe comenzar con una barra diagonal, como
"/path/to/data"
.
Nota: La API de Data Layer solo puede enviar mensajes y sincronizar datos con teléfonos Android o relojes Wear OS. Es decir, si tu dispositivo Wear OS está vinculado con un dispositivo iOS, la API de Data Layer no funcionará.
Por este motivo, no debes usar la API de Data Layer como el método principal para comunicarte con una red. En cambio, sigue el mismo patrón que una app para dispositivos móviles, con algunas diferencias menores.
Por lo general, no se implementa DataItem
directamente. En su lugar, haz lo siguiente:
- Crea un objeto
PutDataRequest
y especifica una ruta de acceso de cadenas para identificar el elemento de forma única. - Llama a
setData()
a fin de configurar la carga útil. - Si una demora en la sincronización perjudica la experiencia del usuario, llama a
setUrgent()
. - Usa el método
putDataItem
de la claseDataClient
para solicitar que el sistema cree el elemento de datos.
Cuando solicite elementos de datos, el sistema mostrará objetos que implementan adecuadamente la interfaz DataItem
. Sin embargo, en lugar de trabajar con bytes sin procesar con setData()
, te recomendamos que uses un mapa de datos, que expone un elemento de datos con una interfaz similar a Bundle
.
Para obtener más información, consulta la app de Ejemplo de DataLayer.
Cómo sincronizar datos con un mapa de datos
Cuando sea posible, usa la clase DataMap
.
Este enfoque te permite trabajar con elementos de datos en el formato de Bundle
de Android, por lo que el sistema realiza la serialización y deserialización de objetos por ti, y tú puedes manipular los datos con pares clave-valor.
Para utilizar un mapa de datos, haz lo siguiente:
- Crea un objeto
PutDataMapRequest
y configura la ruta de acceso del elemento de datos.Nota: La cadena de la ruta de acceso es un identificador exclusivo para el elemento de datos que te permite acceder a él desde ambos extremos de la conexión. La ruta debe comenzar con una barra diagonal. Si usas datos jerárquicos en tu app, crea un esquema de ruta de acceso que coincida con la estructura de los datos.
- Llama a
PutDataMapRequest.getDataMap()
para obtener un mapa de datos en el que puedas establecer valores. -
Configura valores para el mapa de datos con los métodos
put...()
, comoputString()
. - Si una demora en la sincronización perjudica la experiencia del usuario, llama a
setUrgent()
. - Llama a
PutDataMapRequest.asPutDataRequest()
para obtener un objetoPutDataRequest
. - Usa el método
putDataItem
de la claseDataClient
a fin de solicitar que el sistema cree el elemento de datos.Nota: Si el teléfono celular o el dispositivo wearable están desconectados, se almacenan los datos en búfer y se sincronizan cuando se restablece la conexión.
El método increaseCounter()
del siguiente ejemplo muestra cómo crear un mapa de datos y agregarle datos:
Kotlin
private const val COUNT_KEY = "com.example.key.count" class MainActivity : Activity() { private lateinit var dataClient: DataClient private var count = 0 ... // Create a data map and put data in it private fun increaseCounter() { val putDataReq: PutDataRequest = PutDataMapRequest.create("/count").run { dataMap.putInt(COUNT_KEY, count++) asPutDataRequest() } val putDataTask: Task<DataItem> = dataClient.putDataItem(putDataReq) } ... }
Java
public class MainActivity extends Activity { private static final String COUNT_KEY = "com.example.key.count"; private DataClient dataClient; private int count = 0; ... // Create a data map and put data in it private void increaseCounter() { PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count"); putDataMapReq.getDataMap().putInt(COUNT_KEY, count++); PutDataRequest putDataReq = putDataMapReq.asPutDataRequest(); Task<DataItem> putDataTask = dataClient.putDataItem(putDataReq); } ... }
Para obtener más información sobre el manejo de Tasks
, consulta la documentación de referencia.
Cómo establecer la prioridad de DataItem
La API de DataClient
permite solicitudes urgentes para la sincronización de objetos DataItem
.
Por lo general, el sistema retrasa la entrega de los elementos de datos a la red de Wear OS para mejorar la duración de la batería de los dispositivos del usuario, pero si una demora en la sincronización de elementos de datos afecta negativamente la experiencia del usuario, puedes marcarlos como urgentes. Por ejemplo, en el caso de una app de control remoto en la que el usuario espera que se reflejen de inmediato sus acciones, puedes hacer que el sistema sincronice al instante tus elementos de datos con una llamada a setUrgent()
.
Si no llamas a setUrgent()
, el sistema puede tardar hasta 30 minutos en sincronizar los elementos de datos no urgentes. Sin embargo, la demora suele ser de unos pocos minutos. La urgencia predeterminada es "no urgente", por lo que debes usar setUrgent()
si necesitas conservar el comportamiento de sincronización inmediata de las versiones anteriores de la API de Wear OS.
Cómo detectar eventos de elementos de datos
Si un extremo de la conexión de Data Layer modifica un elemento de datos, notifica al usuario cualquier cambio en el otro extremo de la conexión. Puedes lograrlo si implementas un objeto de escucha para eventos de elementos de datos.
El fragmento de código del siguiente ejemplo notifica a tu app cuando cambia el valor del contador definido en el ejemplo anterior:
Kotlin
private const val COUNT_KEY = "com.example.key.count" class MainActivity : Activity(), DataClient.OnDataChangedListener { private var count = 0 override fun onResume() { super.onResume() Wearable.getDataClient(this).addListener(this) } override fun onPause() { super.onPause() Wearable.getDataClient(this).removeListener(this) } override fun onDataChanged(dataEvents: DataEventBuffer) { dataEvents.forEach { event -> // DataItem changed if (event.type == DataEvent.TYPE_CHANGED) { event.dataItem.also { item -> if (item.uri.path.compareTo("/count") == 0) { DataMapItem.fromDataItem(item).dataMap.apply { updateCount(getInt(COUNT_KEY)) } } } } else if (event.type == DataEvent.TYPE_DELETED) { // DataItem deleted } } } // Method to update the count private fun updateCount(int: Int) { ... } ... }
Java
public class MainActivity extends Activity implements DataClient.OnDataChangedListener { private static final String COUNT_KEY = "com.example.key.count"; private int count = 0; @Override protected void onResume() { super.onResume(); Wearable.getDataClient(this).addListener(this); } @Override protected void onPause() { super.onPause(); Wearable.getDataClient(this).removeListener(this); } @Override public void onDataChanged(DataEventBuffer dataEvents) { for (DataEvent event : dataEvents) { if (event.getType() == DataEvent.TYPE_CHANGED) { // DataItem changed DataItem item = event.getDataItem(); if (item.getUri().getPath().compareTo("/count") == 0) { DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap(); updateCount(dataMap.getInt(COUNT_KEY)); } } else if (event.getType() == DataEvent.TYPE_DELETED) { // DataItem deleted } } } // Method to update the count private void updateCount(int c) { ... } ... }
Esta actividad implementa la interfaz DataClient.OnDataChangedListener
. Además, se agrega a sí misma como objeto de escucha para eventos de elementos de datos dentro del método onResume()
y quita el objeto de escucha del método onPause()
. Para ver una implementación con imágenes, modelos de vista y servicios, consulta la app de Ejemplo de DataLayer.
También puedes implementar el objeto de escucha como un servicio. Para obtener más información, consulta Escucha eventos de Data Layer.