page.title=Syncing Data Items @jd:body
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:
"/path/to/data"
)
You normally don't implement DataItem
directly. Instead, you:
PutDataRequest
object,
specifying a string path to uniquely identify the item.
setData()
to set the payload.
DataApi.putDataItem()
to request the system to 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 in an easy-to-use {@link android.os.Bundle}-like interface.
When possible, use the
DataMap
class.
This approach lets you work with data items in the form of an Android {@link android.os.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:
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.
PutDataMapRequest.getDataMap()
to obtain a data map that you can set values on.put...()
methods, such as
putString()
.
PutDataMapRequest.asPutDataRequest()
to obtain a PutDataRequest
object.
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.
In Google Play services 8.3 and later, the {@code DataApi} interface allows urgent requests for syncing of {@code DataItems}. Normally, the system may delay delivery of {@code DataItems} to the Wear network in order to improve battery life for user devices, but if a delay in syncing {@code 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 {@code DataItems} immediately by calling {@code setUrgent()}.
If you do not call {@code setUrgent()}, the system may delay up to 30 minutes before syncing non-urgent {@code 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 {@code setUrgent()} if you wish to retain the immediate-sync behavior that existed in previous versions of the Wear API.
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.onResume(); 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.