Syncing Data Items

A DataItem defines the data interface that the system uses to synchronize data between handhelds and wearables. A DataItem generally consists of the following items:

  • 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")

You normally don't implement DataItem directly. Instead, you:

  1. Create a PutDataRequest object, specifying a string path to uniquely identify the item.
  2. Call setData() to set the payload.
  3. Call DataApi.putDataItem() to request the system to create the data item.
  4. 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 in an easy-to-use Bundle-like interface.

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 object serialization and de-serialization is done for you, and you can manipulate data with key-value pairs.

To use a data map:

  1. 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.

  2. Call PutDataMapRequest.getDataMap() to obtain a data map that you can set values on.
  3. Set any desired values for the data map using the put...() methods, such as putString().
  4. Call PutDataMapRequest.asPutDataRequest() to obtain a PutDataRequest object.
  5. Call DataApi.putDataItem() to request the system to 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:

public class MainActivity extends Activity implements
       
DataApi.DataListener,
       
GoogleApiClient.ConnectionCallbacks,
       
GoogleApiClient.OnConnectionFailedListener {

   
private static final String COUNT_KEY = "com.example.key.count";

   
private GoogleApiClient mGoogleApiClient;
   
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();
       
PendingResult<DataApi.DataItemResult> pendingResult =
               
Wearable.DataApi.putDataItem(mGoogleApiClient, putDataReq);
   
}

   
...
}

For more information about handling the PendingResult object, see Wait for the Status of Data Layer Calls.

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:

public class MainActivity extends Activity implements
       
DataApi.DataListener,
       
GoogleApiClient.ConnectionCallbacks,
       
GoogleApiClient.OnConnectionFailedListener {

   
private static final String COUNT_KEY = "com.example.key.count";

   
private GoogleApiClient mGoogleApiClient;
   
private int count = 0;

   
@Override
   
protected void onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
        setContentView
(R.layout.activity_main);

        mGoogleApiClient
= new GoogleApiClient.Builder(this)
               
.addApi(Wearable.API)
               
.addConnectionCallbacks(this)
               
.addOnConnectionFailedListener(this)
               
.build();
   
}

   
@Override
   
protected void onResume() {
       
super.onStart();
        mGoogleApiClient
.connect();
   
}

   
@Override
   
public void onConnected(Bundle bundle) {
       
Wearable.DataApi.addListener(mGoogleApiClient, this);
   
}

   
@Override
   
protected void onPause() {
       
super.onPause();
       
Wearable.DataApi.removeListener(mGoogleApiClient, this);
        mGoogleApiClient
.disconnect();
   
}

   
@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 DataItem.DataListener interface. This activity adds itself as a listener for data item events inside the onConnected() 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.