A DataItem
defines the interface that the system uses to synchronize data between handhelds and
wearables. A DataItem
generally consists of the following components:
- Payload — A byte array, which you can set with whatever data you wish, allowing you to do your own object serialization and deserialization. The size of the payload is limited to 100KB.
-
Path — A unique string that must start with a forward slash
(for instance,
"/path/to/data"
)
Note: A Wear app can communicate with a phone app using the Data Layer API, but connecting to a network using this API is discouraged.
You normally don't implement DataItem
directly. Instead, you do the following:
-
Create a
PutDataRequest
object, specifying a string path to uniquely identify the item. -
Call
setData()
to set the payload. -
If a delay in syncing would negatively impact user experience, call
setUrgent()
. -
Use the
putDataItem
method of theDataClient
class to request that the system create the data item.
When requesting data items, the system returns objects that properly implement the
DataItem
interface. However, instead of working with raw bytes using
setData()
, we recommend you
use a data map,
which exposes a data item with an easy-to-use Bundle
-like interface.
Refer to the following related resources:
Sync data with a data map
When possible, use the
DataMap
class.
This approach lets you work with data items in the form of an Android Bundle
,
so the system does object serialization and deserialization for you, and you can manipulate data
with key-value pairs.
To use a data map:
-
Create a
PutDataMapRequest
object, setting the path of the data item.Note: The path string is a unique identifier for the data item that allows you to access it from either side of the connection. The path must begin with a forward slash. If you're using hierarchical data in your app, you should create a path scheme that matches the structure of the data.
-
Call
PutDataMapRequest.getDataMap()
to obtain a data map that you can set values on. -
Set any desired values for the data map using the
put...()
methods, such asputString()
. -
If a delay in syncing would negatively impact user experience, call
setUrgent()
. -
Call
PutDataMapRequest.asPutDataRequest()
to obtain aPutDataRequest
object. -
Use the
putDataItem
method of theDataClient
class to request that the system create the data item.Note: If the handset and wearable devices are disconnected, the data is buffered and synced when the connection is re-established.
The increaseCounter()
method in the following example shows how to create a
data map and put data in it:
Kotlin
private const val COUNT_KEY = "com.example.key.count" class MainActivity : Activity() { private lateinit var mDataClient: 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> = mDataClient.putDataItem(putDataReq) } ... }
Java
public class MainActivity extends Activity { private static final String COUNT_KEY = "com.example.key.count"; private DataClient mDataClient; 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 = mDataClient.putDataItem(putDataReq); } ... }
For more information about handling
Tasks
, see the
reference documentation.
Set DataItem priority
The
DataClient
API allows urgent requests for syncing of
DataItems
.
Normally, the system may delay delivery of
DataItems
to the Wear network in order to improve battery life for user devices, but
if a delay in syncing
DataItems
would negatively impact user experience, you can mark
them as urgent. For example, in a remote control app where the user expects their
actions to be reflected immediately, you can have the system sync your
DataItems
immediately by calling
setUrgent()
.
If you do not call
setUrgent()
, the system may delay up to 30 minutes before syncing non-urgent
DataItems
,
but you can usually expect the delay to be a few minutes, if at all.
The default urgency is now non-urgent, so you must use
setUrgent()
if you wish to retain the immediate-sync behavior that
existed in previous versions of the Wear API.
Listen for data item events
If one side of the data layer connection changes a data item, you probably want to be notified of any changes on the other side of the connection. You can do this by implementing a listener for data item events.
The code snippet in the following example notifies your app when the value of the counter defined in the previous example changes:
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) { ... } ... }
This activity implements the
DataClient.OnDataChangedListener
interface. This activity adds itself
as a listener for data item events inside
the onResume()
method and removes the listener in the
onPause()
method.
You can also implement the listener as a service. For more information, see Listen for data layer events.