1page.title=Syncing Data Items
2
3@jd:body
4
5<div id="tb-wrapper">
6<div id="tb">
7
8<h2>This lesson teaches you to</h2>
9<ol>
10  <li><a href="#SyncData">Sync Data with a Data Map</a></li>
11  <li><a href="#ListenEvents">Listen for Data Item Events</a></li>
12</ol>
13
14</div>
15</div>
16
17<p>
18A <a href="{@docRoot}reference/com/google/android/gms/wearable/DataItem.html"><code>DataItem</code></a>
19defines the data interface that the system uses to synchronize data between handhelds
20and wearables. A <a href="{@docRoot}reference/com/google/android/gms/wearable/DataItem.html"><code>DataItem</code></a> generally
21consists of the following items:</p>
22<ul>
23  <li><b>Payload</b> - A byte array, which you can set with whatever data you wish, allowing you
24  to do your own object serialization and deserialization. The size of the payload is limited
25  to 100KB.</li>
26  <li><b>Path</b> - A unique string that must start with a forward slash (for instance,
27  <code>"/path/to/data"</code>)</li>
28</ul>
29
30<p>
31You normally don't implement <a href="{@docRoot}reference/com/google/android/gms/wearable/DataItem.html"><code>DataItem</code></a>
32directly. Instead, you:
33
34<ol>
35  <li>Create a <a href="{@docRoot}reference/com/google/android/gms/wearable/PutDataRequest.html"><code>PutDataRequest</code></a> object,
36  specifying a string path to uniquely identify the item.
37  </li>
38  <li>Call <a href="{@docRoot}reference/com/google/android/gms/wearable/PutDataRequest.html#setData(byte[])">
39  <code>setData()</code></a> to set the payload.
40  </li>
41  <li>Call <a href="{@docRoot}reference/com/google/android/gms/wearable/DataApi.html#putDataItem(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.wearable.PutDataRequest)"><code>DataApi.putDataItem()</code></a> to request the system to create the data item.
42  </li>
43  <li>When requesting data items, the system returns objects
44  that properly implement the <a href="{@docRoot}reference/com/google/android/gms/wearable/DataItem.html"><code>DataItem</code></a> interface.
45  </li>
46</ol>
47
48<p>
49However, instead of working with raw bytes using <a href="{@docRoot}reference/com/google/android/gms/wearable/PutDataRequest.html#setData(byte[])"><code>setData()</code></a>,
50we recommend you <a href="#SyncData">use a data map</a>, which exposes
51a data item in an easy-to-use {@link android.os.Bundle}-like interface.
52</p>
53
54
55<h2 id="SyncData">Sync Data with a Data Map</h2>
56<p>
57When possible, use the <a href="{@docRoot}reference/com/google/android/gms/wearable/DataMap.html"><code>DataMap</code></a> class.
58This approach lets you work with data items in the form of an Android {@link android.os.Bundle},
59so object serialization and de-serialization is done for you, and you can manipulate data with key-value pairs.
60</p>
61
62<p>To use a data map:</p>
63
64<ol>
65  <li>Create a
66<a href="{@docRoot}reference/com/google/android/gms/wearable/PutDataMapRequest.html"><code>PutDataMapRequest</code></a>
67object, setting the path of the data item.
68<p class="note"><b>Note:</b> The path string is a unique identifier for the
69data item that allows you to access it from either side of the connection. The path must begin
70with a forward slash. If you're using hierarchical data in your
71app, you should create a path scheme that matches the structure of the data.
72</p>
73</li>
74<li>Call
75<a href="{@docRoot}reference/com/google/android/gms/wearable/PutDataMapRequest.html#getDataMap()"><code>PutDataMapRequest.getDataMap()</code></a>
76</a> to obtain a data map that you can set values on.</li>
77  <li>Set any desired values for the data map using the <code>put...()</code> methods, such as
78  <a href="{@docRoot}reference/com/google/android/gms/wearable/DataMap.html#putString(java.lang.String, java.lang.String)"><code>putString()</code></a>.
79  </li>
80  <li>Call <a href="{@docRoot}reference/com/google/android/gms/wearable/PutDataMapRequest.html#asPutDataRequest()"><code>PutDataMapRequest.asPutDataRequest()</code></a>
81  to obtain a <a href="{@docRoot}reference/com/google/android/gms/wearable/PutDataRequest.html"><code>PutDataRequest</code></a> object.
82   </li>
83  <li>Call <a href="{@docRoot}reference/com/google/android/gms/wearable/DataApi.html#putDataItem(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.wearable.PutDataRequest)"><code>DataApi.putDataItem()</code></a> to request the system to create the data item.
84  <p class="note"><b>Note:</b>
85  If the handset and wearable devices are disconnected,
86  the data is buffered and synced when the connection is re-established.
87  </p>
88  </li>
89</ol>
90
91<p>The <code>increaseCounter()</code> method in the following example shows how to create a
92data map and put data in it:</p>
93
94<pre>
95public class MainActivity extends Activity implements
96        DataApi.DataListener,
97        GoogleApiClient.ConnectionCallbacks,
98        GoogleApiClient.OnConnectionFailedListener {
99
100    private static final String COUNT_KEY = "com.example.key.count";
101
102    private GoogleApiClient mGoogleApiClient;
103    private int count = 0;
104
105    ...
106
107    // Create a data map and put data in it
108    private void <strong>increaseCounter</strong>() {
109        PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count");
110        putDataMapReq.getDataMap().putInt(COUNT_KEY, count++);
111        PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();
112        PendingResult&lt;DataApi.DataItemResult> pendingResult =
113                Wearable.DataApi.putDataItem(mGoogleApiClient, putDataReq);
114    }
115
116    ...
117}
118</pre>
119
120<p>For more information about handling the
121<a href="{@docRoot}reference/com/google/android/gms/common/api/PendingResult.html">
122<code>PendingResult</code></a> object, see
123<a href="{@docRoot}training/wearables/data-layer/events.html#Wait">Wait for the Status of Data
124Layer Calls</a>.</p>
125
126
127<h2 id="ListenEvents">Listen for Data Item Events</h2>
128
129<p>If one side of the data layer connection changes a data item, you probably want
130to be notified of any changes on the other side of the connection.
131You can do this by implementing a listener for data item events.</p>
132
133<p>The code snippet in the following example notifies your app when the value of the
134counter defined in the previous example changes:</p>
135
136<pre>
137public class MainActivity extends Activity implements
138        DataApi.DataListener,
139        GoogleApiClient.ConnectionCallbacks,
140        GoogleApiClient.OnConnectionFailedListener {
141
142    private static final String COUNT_KEY = "com.example.key.count";
143
144    private GoogleApiClient mGoogleApiClient;
145    private int count = 0;
146
147    &#64;Override
148    protected void onCreate(Bundle savedInstanceState) {
149        super.onCreate(savedInstanceState);
150        setContentView(R.layout.activity_main);
151
152        mGoogleApiClient = new GoogleApiClient.Builder(this)
153                .addApi(Wearable.API)
154                .addConnectionCallbacks(this)
155                .addOnConnectionFailedListener(this)
156                .build();
157    }
158
159    &#64;Override
160    protected void onResume() {
161        super.onStart();
162        mGoogleApiClient.connect();
163    }
164
165    &#64;Override
166    public void onConnected(Bundle bundle) {
167        <strong>Wearable.DataApi.addListener</strong>(mGoogleApiClient, this);
168    }
169
170    &#64;Override
171    protected void onPause() {
172        super.onPause();
173        <strong>Wearable.DataApi.removeListener</strong>(mGoogleApiClient, this);
174        mGoogleApiClient.disconnect();
175    }
176
177    &#64;Override
178    public void <strong>onDataChanged</strong>(DataEventBuffer dataEvents) {
179        for (DataEvent event : dataEvents) {
180            if (event.getType() == DataEvent.TYPE_CHANGED) {
181                // DataItem changed
182                DataItem item = event.getDataItem();
183                if (item.getUri().getPath().compareTo("/count") == 0) {
184                    DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap();
185                    updateCount(dataMap.getInt(COUNT_KEY));
186                }
187            } else if (event.getType() == DataEvent.TYPE_DELETED) {
188                // DataItem deleted
189            }
190        }
191    }
192
193    // Our method to update the count
194    private void updateCount(int c) { ... }
195
196    ...
197}
198</pre>
199
200<p>This activity implements the
201<a href="{@docRoot}reference/com/google/android/gms/wearable/DataApi.DataListener.html">
202<code>DataItem.DataListener</code></a> interface. This activity adds itself as a listener
203for data item events inside the <code>onConnected()</code> method and removes the listener
204in the <code>onPause()</code> method.</p>
205
206<p>You can also implement the listener as a service. For more information, see
207<a href="{@docRoot}training/wearables/data-layer/events.html#Listen">Listen for Data Layer
208Events</a>.</p>
209