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: es un arreglo de bytes que puedes configurar con los datos que quieras, 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: es una string única que debe comenzar con una barra diagonal (por ejemplo,
"/path/to/data"
).
Nota: Una app para Wear puede comunicarse con una aplicación para teléfonos usando la API de Data Layer, pero no es recomendable conectarse a una red con esta API.
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 strings 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 mediante setData()
, te recomendamos que uses un mapa de datos, que expone un elemento de datos con una interfaz similar a Bundle
fácil de usar.
Consulta los siguientes recursos relacionados:
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 string 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, debes crear un esquema de ruta de acceso que coincida con la estructura de los datos.
- Llama a
PutDataMapRequest.getDataMap()
a fin de obtener un mapa de datos en el que puedas establecer valores. - Configura los valores deseados 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
admite solicitudes urgentes para la sincronización de DataItems
.
Por lo general, el sistema puede retrasar la publicación de DataItems
en la red de Wear a los efectos de extender la duración de batería de los dispositivos del usuario, pero, si una demora en la sincronización de DataItems
perjudica 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 inmediatamente sus acciones, puedes hacer que el sistema sincronice al instante tus DataItems
llamando a setUrgent()
.
Si no llamas a setUrgent()
, el sistema puede tardar hasta 30 minutos en sincronizar los DataItems
no urgentes. No obstante, la demora suele ser de unos pocos minutos, si es que se produce.
La urgencia predeterminada ahora es "no urgente", por lo que debes usar setUrgent()
si quieres conservar el comportamiento de sincronización inmediata presente en versiones anteriores de la API de Wear.
Cómo escuchar eventos de elementos de datos
Si un extremo de la conexión de Data Layer modifica un elemento de datos, es probable que quieras recibir notificaciones sobre cambios 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 } } } // Our 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 } } } // Our 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()
.
También puedes implementar el objeto de escucha como un servicio. Para obtener más información, consulta Cómo escuchar eventos de Data Layer.