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 42 <li> 43 If a delay in syncing would negatively impact user experience, call 44 <a href="{@docRoot}reference/com/google/android/gms/wearable/PutDataRequest#setUrgent()"> 45 {@code setUrgent()}</a>. 46 </li> 47 48 <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. 49 </li> 50 </ol> 51 52<p> 53When requesting data items, the system returns objects that properly implement the 54<a href="{@docRoot}reference/com/google/android/gms/wearable/DataItem.html"><code>DataItem</code> 55</a> interface. However, instead of working with raw bytes using 56<a href="{@docRoot}reference/com/google/android/gms/wearable/PutDataRequest.html#setData(byte[])"> 57<code>setData()</code></a>, we recommend you <a href="#SyncData">use a data map</a>, which exposes 58a data item in an easy-to-use {@link android.os.Bundle}-like interface. 59</p> 60 61 62<h2 id="SyncData">Sync Data with a Data Map</h2> 63<p> 64When possible, use the <a href="{@docRoot}reference/com/google/android/gms/wearable/DataMap.html"> 65<code>DataMap</code></a> class. 66This approach lets you work with data items in the form of an Android {@link android.os.Bundle}, 67so the system does object serialization and deserialization for you, and you can manipulate data 68with key-value pairs. 69</p> 70 71<p>To use a data map:</p> 72 73<ol> 74 <li>Create a 75<a href="{@docRoot}reference/com/google/android/gms/wearable/PutDataMapRequest.html"><code>PutDataMapRequest</code></a> 76object, setting the path of the data item. 77<p class="note"><b>Note:</b> The path string is a unique identifier for the 78data item that allows you to access it from either side of the connection. The path must begin 79with a forward slash. If you're using hierarchical data in your 80app, you should create a path scheme that matches the structure of the data. 81</p> 82</li> 83<li>Call 84<a href="{@docRoot}reference/com/google/android/gms/wearable/PutDataMapRequest.html#getDataMap()"><code>PutDataMapRequest.getDataMap()</code></a> 85</a> to obtain a data map that you can set values on.</li> 86 <li>Set any desired values for the data map using the <code>put...()</code> methods, such as 87 <a href="{@docRoot}reference/com/google/android/gms/wearable/DataMap.html#putString(java.lang.String, java.lang.String)"><code>putString()</code></a>. 88 </li> 89 90 <li> 91 If a delay in syncing would negatively impact user experience, call 92 <a href="{@docRoot}reference/com/google/android/gms/wearable/PutDataRequest#setUrgent()"> 93 {@code setUrgent()}</a>. 94 </li> 95 96 97 <li>Call <a href="{@docRoot}reference/com/google/android/gms/wearable/PutDataMapRequest.html#asPutDataRequest()"><code>PutDataMapRequest.asPutDataRequest()</code></a> 98 to obtain a <a href="{@docRoot}reference/com/google/android/gms/wearable/PutDataRequest.html"><code>PutDataRequest</code></a> object. 99 </li> 100 101 102 <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. 103 104 <p class="note"><b>Note:</b> 105 106 If the handset and wearable devices are disconnected, 107 the data is buffered and synced when the connection is re-established. 108 </p> 109 </li> 110</ol> 111 112<p>The <code>increaseCounter()</code> method in the following example shows how to create a 113data map and put data in it:</p> 114 115<pre> 116public class MainActivity extends Activity implements 117 DataApi.DataListener, 118 GoogleApiClient.ConnectionCallbacks, 119 GoogleApiClient.OnConnectionFailedListener { 120 121 private static final String COUNT_KEY = "com.example.key.count"; 122 123 private GoogleApiClient mGoogleApiClient; 124 private int count = 0; 125 126 ... 127 128 // Create a data map and put data in it 129 private void <strong>increaseCounter</strong>() { 130 PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count"); 131 putDataMapReq.getDataMap().putInt(COUNT_KEY, count++); 132 PutDataRequest putDataReq = putDataMapReq.asPutDataRequest(); 133 PendingResult<DataApi.DataItemResult> pendingResult = 134 Wearable.DataApi.putDataItem(mGoogleApiClient, putDataReq); 135 } 136 137 ... 138} 139</pre> 140 141<p>For more information about handling the 142<a href="{@docRoot}reference/com/google/android/gms/common/api/PendingResult.html"> 143<code>PendingResult</code></a> object, see 144<a href="{@docRoot}training/wearables/data-layer/events.html#Wait">Wait for the Status of Data 145Layer Calls</a>.</p> 146 147 148<h3>Set DataItem priority</h3> 149 150<p> 151In <a href="https://developers.google.com/android/guides/releases">Google Play services 8.3 and later</a>, 152the 153<a href="{@docRoot}reference/com/google/android/gms/wearable/DataApi">{@code DataApi}</a> interface 154allows urgent requests for syncing of 155<a href="{@docRoot}reference/com/google/android/gms/wearable/DataItem">{@code DataItems}</a>. 156Normally, the system may delay delivery of 157<a href="{@docRoot}reference/com/google/android/gms/wearable/DataItem">{@code DataItems}</a> 158to the Wear network in order to improve battery life 159for user devices, but if a delay in syncing 160<a href="{@docRoot}reference/com/google/android/gms/wearable/DataItem">{@code DataItems}</a> 161would negatively impact user experience, you 162can mark them as urgent. For example, in a remote control app where the user expects their actions to be 163reflected immediately, you can have the system sync your 164<a href="{@docRoot}reference/com/google/android/gms/wearable/DataItem">{@code DataItems}</a> 165immediately by calling 166<a href="{@docRoot}reference/com/google/android/gms/wearable/PutDataRequest#setUrgent()"> 167{@code setUrgent()}</a>. 168</p> 169 170<p> 171If you do not call 172<a href="{@docRoot}reference/com/google/android/gms/wearable/PutDataRequest#setUrgent()"> 173{@code setUrgent()}</a>, the system may delay up to 30 minutes before syncing non-urgent 174<a href="{@docRoot}reference/com/google/android/gms/wearable/DataItem">{@code DataItems}</a>, 175but you can usually expect the delay to be a few minutes, if at all. 176The default urgency is now non-urgent, so you must use 177<a href="{@docRoot}reference/com/google/android/gms/wearable/PutDataRequest#setUrgent()"> 178{@code setUrgent()}</a> if you wish to retain the immediate-sync behavior that 179existed in previous versions of the Wear API. 180</p> 181 182<h2 id="ListenEvents">Listen for Data Item Events</h2> 183 184<p>If one side of the data layer connection changes a data item, you probably want 185to be notified of any changes on the other side of the connection. 186You can do this by implementing a listener for data item events.</p> 187 188<p>The code snippet in the following example notifies your app when the value of the 189counter defined in the previous example changes:</p> 190 191<pre> 192public class MainActivity extends Activity implements 193 DataApi.DataListener, 194 GoogleApiClient.ConnectionCallbacks, 195 GoogleApiClient.OnConnectionFailedListener { 196 197 private static final String COUNT_KEY = "com.example.key.count"; 198 199 private GoogleApiClient mGoogleApiClient; 200 private int count = 0; 201 202 @Override 203 protected void onCreate(Bundle savedInstanceState) { 204 super.onCreate(savedInstanceState); 205 setContentView(R.layout.activity_main); 206 207 mGoogleApiClient = new GoogleApiClient.Builder(this) 208 .addApi(Wearable.API) 209 .addConnectionCallbacks(this) 210 .addOnConnectionFailedListener(this) 211 .build(); 212 } 213 214 @Override 215 protected void onResume() { 216 super.onResume(); 217 mGoogleApiClient.connect(); 218 } 219 220 @Override 221 public void onConnected(Bundle bundle) { 222 <strong>Wearable.DataApi.addListener</strong>(mGoogleApiClient, this); 223 } 224 225 @Override 226 protected void onPause() { 227 super.onPause(); 228 <strong>Wearable.DataApi.removeListener</strong>(mGoogleApiClient, this); 229 mGoogleApiClient.disconnect(); 230 } 231 232 @Override 233 public void <strong>onDataChanged</strong>(DataEventBuffer dataEvents) { 234 for (DataEvent event : dataEvents) { 235 if (event.getType() == DataEvent.TYPE_CHANGED) { 236 // DataItem changed 237 DataItem item = event.getDataItem(); 238 if (item.getUri().getPath().compareTo("/count") == 0) { 239 DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap(); 240 updateCount(dataMap.getInt(COUNT_KEY)); 241 } 242 } else if (event.getType() == DataEvent.TYPE_DELETED) { 243 // DataItem deleted 244 } 245 } 246 } 247 248 // Our method to update the count 249 private void updateCount(int c) { ... } 250 251 ... 252} 253</pre> 254 255<p>This activity implements the 256<a href="{@docRoot}reference/com/google/android/gms/wearable/DataApi.DataListener.html"> 257<code>DataItem.DataListener</code></a> interface. This activity adds itself as a listener 258for data item events inside the <code>onConnected()</code> method and removes the listener 259in the <code>onPause()</code> method.</p> 260 261<p>You can also implement the listener as a service. For more information, see 262<a href="{@docRoot}training/wearables/data-layer/events.html#Listen">Listen for Data Layer 263Events</a>.</p> 264