Home | History | Annotate | Download | only in data-layer
      1 page.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>
     18 A <a href="{@docRoot}reference/com/google/android/gms/wearable/DataItem.html"><code>DataItem</code></a>
     19 defines the data interface that the system uses to synchronize data between handhelds
     20 and wearables. A <a href="{@docRoot}reference/com/google/android/gms/wearable/DataItem.html"><code>DataItem</code></a> generally
     21 consists 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>
     31 You normally don't implement <a href="{@docRoot}reference/com/google/android/gms/wearable/DataItem.html"><code>DataItem</code></a>
     32 directly. 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>
     49 However, instead of working with raw bytes using <a href="{@docRoot}reference/com/google/android/gms/wearable/PutDataRequest.html#setData(byte[])"><code>setData()</code></a>,
     50 we recommend you <a href="#SyncData">use a data map</a>, which exposes
     51 a 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>
     57 When possible, use the <a href="{@docRoot}reference/com/google/android/gms/wearable/DataMap.html"><code>DataMap</code></a> class.
     58 This approach lets you work with data items in the form of an Android {@link android.os.Bundle},
     59 so 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>
     67 object, setting the path of the data item.
     68 <p class="note"><b>Note:</b> The path string is a unique identifier for the
     69 data item that allows you to access it from either side of the connection. The path must begin
     70 with a forward slash. If you're using hierarchical data in your
     71 app, 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
     92 data map and put data in it:</p>
     93 
     94 <pre>
     95 public 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
    124 Layer 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
    130 to be notified of any changes on the other side of the connection.
    131 You 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
    134 counter defined in the previous example changes:</p>
    135 
    136 <pre>
    137 public 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
    203 for data item events inside the <code>onConnected()</code> method and removes the listener
    204 in 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
    208 Events</a>.</p>
    209