12728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lypage.title=Handling Data Layer Events 22728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 32728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly@jd:body 42728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 52728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<div id="tb-wrapper"> 62728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<div id="tb"> 72728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 82728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<h2>This lesson teaches you to</h2> 92728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<ol> 102728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly <li><a href="#Wait">Wait for the Status of Data Layer Calls</a></li> 112728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly <li><a href="#Listen">Listen for Data Layer Events</a></li> 122728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly</ol> 132728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 142728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly</div> 152728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly</div> 162728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 17eff209d2c40221d2f9be2fd6b0c9cde51dd5362bRicardo Cervera<p>When you make calls to the Data Layer API, you can receive the status 182728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lyof the call when it completes as well as listen for any changes that 192728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lythe call ends up making with listeners. 202728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly</p> 212728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 222728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<h2 id="Wait">Wait for the Status of Data Layer Calls</h2> 232728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 24eff209d2c40221d2f9be2fd6b0c9cde51dd5362bRicardo Cervera<p>You'll notice that calls to the Data Layer API sometimes return a 252728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<a href="{@docRoot}reference/com/google/android/gms/common/api/PendingResult.html"><code>PendingResult</code></a>, 262728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lysuch as 272728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<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>putDataItem()</code></a>. 282728c2a93abd74ef19e550f3530ee70ea41424b3Robert LyAs soon as the <a href="{@docRoot}reference/com/google/android/gms/common/api/PendingResult.html"><code>PendingResult</code></a> is created, 292728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lythe operation is queued in the background. If you do nothing else after this, the operation 302728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lyeventually completes silently. However, you'll usually want to do something with the result 312728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lyafter the operation completes, so the 322728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<a href="{@docRoot}reference/com/google/android/gms/common/api/PendingResult.html"><code>PendingResult</code></a> 332728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lylets you wait for the result status, either synchronously or asynchronously. 342728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly</p> 352728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 36eff209d2c40221d2f9be2fd6b0c9cde51dd5362bRicardo Cervera<h3 id="async-waiting">Asynchronous calls</h3> 37eff209d2c40221d2f9be2fd6b0c9cde51dd5362bRicardo Cervera<p>If your code is running on the main UI thread, do not make blocking calls 38eff209d2c40221d2f9be2fd6b0c9cde51dd5362bRicardo Cerverato the Data Layer API. You can run the calls asynchronously by adding a callback method 392728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lyto the <a href="{@docRoot}reference/com/google/android/gms/common/api/PendingResult.html"><code>PendingResult</code></a> object, 402728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lywhich fires when the operation is completed:</p> 412728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<pre> 422728c2a93abd74ef19e550f3530ee70ea41424b3Robert LypendingResult.setResultCallback(new ResultCallback<DataItemResult>() { 432728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly @Override 442728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly public void onResult(final DataItemResult result) { 452728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly if(result.getStatus().isSuccess()) { 467a04794186dcb679501a7a9383caae8df01428d0Chris Smith Log.d(TAG, "Data item set: " + result.getDataItem().getUri()); 477a04794186dcb679501a7a9383caae8df01428d0Chris Smith } 482728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly } 492728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly}); 502728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly</pre> 512728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 52eff209d2c40221d2f9be2fd6b0c9cde51dd5362bRicardo Cervera<h3 id="sync-waiting">Synchronous calls</h3> 532728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<p>If your code is running on a separate handler thread in a background service (which is the case 542728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lyin a <a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"><code>WearableListenerService</code></a>), 552728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lyit's fine for the calls to block. In this case, you can call 562728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<a href="{@docRoot}reference/com/google/android/gms/common/api/PendingResult.html#await()"><code>await()</code></a> 57eff209d2c40221d2f9be2fd6b0c9cde51dd5362bRicardo Cerveraon the <a href="{@docRoot}reference/com/google/android/gms/common/api/PendingResult.html"><code>PendingResult</code></a> 58eff209d2c40221d2f9be2fd6b0c9cde51dd5362bRicardo Cerveraobject, which blocks until the request completes and returns a 59eff209d2c40221d2f9be2fd6b0c9cde51dd5362bRicardo Cervera<a href="{@docRoot}reference/com/google/android/gms/common/api/Result.html"><code>Result</code></a> 602728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lyobject: 612728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly</p> 622728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 632728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<pre> 642728c2a93abd74ef19e550f3530ee70ea41424b3Robert LyDataItemResult result = pendingResult.await(); 652728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lyif(result.getStatus().isSuccess()) { 662728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly Log.d(TAG, "Data item set: " + result.getDataItem().getUri()); 672728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly} 682728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly</pre> 692728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 702728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 712728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<h2 id="Listen">Listen for Data Layer Events </h2> 722728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<p>Because the data layer synchronizes and sends data across the handheld and 732728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lywearable, you normally want to listen for important events, such as when data items 742728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lyare created, messages are received, or when the wearable and handset are connected. 752728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly</p> 762728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<p>To listen for data layer events, you have two options:</p> 772728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 782728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<ul> 792728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly <li>Create a service that extends 802728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly <a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"><code>WearableListenerService</code></a>. 812728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly </li> 822728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly <li>Create an activity that implements 832728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly <a href="{@docRoot}reference/com/google/android/gms/wearable/DataApi.DataListener.html"><code>DataApi.DataListener</code></a>. 842728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly </li> 852728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly</ul> 862728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 87eff209d2c40221d2f9be2fd6b0c9cde51dd5362bRicardo Cervera<p>With both these options, you override the data event callback methods for the events you 88eff209d2c40221d2f9be2fd6b0c9cde51dd5362bRicardo Cerveraare interested in handling.</p> 892728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 902728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<h3 id="listener-service">With a WearableListenerService</h3> 912728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 922728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<p> 932728c2a93abd74ef19e550f3530ee70ea41424b3Robert LyYou typically create instances of this service in both your wearable and handheld apps. If you 94eff209d2c40221d2f9be2fd6b0c9cde51dd5362bRicardo Cerveraare not interested in data events in one of these apps, then you don't need to implement this 952728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lyservice in that particular app.</p> 962728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 972728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<p>For example, you can have a handheld app that sets and gets data item objects and a wearable app 982728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lythat listens for these updates to update it's UI. The wearable never updates any of the data items, 992728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lyso the handheld app doesn't listen for any data events from the wearable app.</p> 1002728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 1012728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<p>You can listen for the following events with 1022728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"><code>WearableListenerService</code></a>:</p> 1032728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 1042728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<ul> 1052728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly <li><a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html#onDataChanged(com.google.android.gms.wearable.DataEventBuffer)"><code>onDataChanged()</code></a> 1062728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly- Called when data item objects are created, changed, or deleted. An event on one side of a connection 107321e030202cb74cad0dd8a4950cffe361a5072c8Ricardo Cerveratriggers this callback on both sides.</li> 1082728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly <li><a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html#onMessageReceived(com.google.android.gms.wearable.MessageEvent)"><code>onMessageReceived()</code></a> 1092728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly- A message sent from one side of a connection triggers this callback on the other side of the connection.</li> 1102728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly <li><a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html#onMessageReceived(com.google.android.gms.wearable.MessageEvent)"><code>onPeerConnected()</code></a> 1112728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly and <a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html#onPeerDisconnected(com.google.android.gms.wearable.Node)"><code>onPeerDisconnected()</code></a> - 112eff209d2c40221d2f9be2fd6b0c9cde51dd5362bRicardo Cervera Called when the connection with the handheld or wearable is connected or disconnected. 113eff209d2c40221d2f9be2fd6b0c9cde51dd5362bRicardo Cervera Changes in connection state on one side of the connection trigger these callbacks on both sides 114eff209d2c40221d2f9be2fd6b0c9cde51dd5362bRicardo Cervera of the connection. 1152728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly </li> 1162728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly</ul> 1172728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 1182728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<p>To create a <a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"><code>WearableListenerService</code></a>:</p> 1192728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 1202728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<ol> 1212728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly <li>Create a class that extends 1222728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly <a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"><code>WearableListenerService</code></a>. 1232728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly </li> 124eff209d2c40221d2f9be2fd6b0c9cde51dd5362bRicardo Cervera <li>Listen for the events that you're interested in, such as 125eff209d2c40221d2f9be2fd6b0c9cde51dd5362bRicardo Cervera <a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html#onDataChanged(com.google.android.gms.wearable.DataEventBuffer)"><code>onDataChanged()</code></a>. 1262728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly </li> 1272728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly <li>Declare an intent filter in your Android manifest to notify the system about your 1282728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly <a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"><code>WearableListenerService</code></a>. 1292728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly This allows the system to bind your service as needed. 1302728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly </li> 1312728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly</ol> 1322728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 1332728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly <p>The following example shows how to implement a simple 1342728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly <a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"><code>WearableListenerService</code></a>: 1352728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly </p> 1362728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 1372728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<pre> 1382728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lypublic class DataLayerListenerService extends WearableListenerService { 1392728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 1402728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly private static final String TAG = "DataLayerSample"; 1412728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly private static final String START_ACTIVITY_PATH = "/start-activity"; 1422728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly private static final String DATA_ITEM_RECEIVED_PATH = "/data-item-received"; 1432728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 1442728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly @Override 1452728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly public void onDataChanged(DataEventBuffer dataEvents) { 1462728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly if (Log.isLoggable(TAG, Log.DEBUG)) { 1472728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly Log.d(TAG, "onDataChanged: " + dataEvents); 1482728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly } 1492728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly final List<DataEvent> events = FreezableUtils 1502728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly .freezeIterable(dataEvents); 1512728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 1522728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly GoogleApiClient googleApiClient = new GoogleApiClient.Builder(this) 1532728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly .addApi(Wearable.API) 1542728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly .build(); 1552728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 1562728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly ConnectionResult connectionResult = 1572728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly googleApiClient.blockingConnect(30, TimeUnit.SECONDS); 1582728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 1592728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly if (!connectionResult.isSuccess()) { 1602728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly Log.e(TAG, "Failed to connect to GoogleApiClient."); 1612728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly return; 1622728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly } 1632728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 1642728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly // Loop through the events and send a message 165bcb15cc1b16f64c6ab3f22b19b6fd7daff48304aLuan Nguyen // to the node that created the data item. 1662728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly for (DataEvent event : events) { 1672728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly Uri uri = event.getDataItem().getUri(); 1682728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 1692728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly // Get the node id from the host value of the URI 1702728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly String nodeId = uri.getHost(); 171eff209d2c40221d2f9be2fd6b0c9cde51dd5362bRicardo Cervera // Set the data of the message to be the bytes of the URI 1722728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly byte[] payload = uri.toString().getBytes(); 1732728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 1742728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly // Send the RPC 1752728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly Wearable.MessageApi.sendMessage(googleApiClient, nodeId, 1762728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly DATA_ITEM_RECEIVED_PATH, payload); 1772728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly } 1782728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly } 1792728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly} 180321e030202cb74cad0dd8a4950cffe361a5072c8Ricardo Cervera</pre> 1812728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 1822728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<p>Here's the corresponding intent filter in the Android manifest file:</p> 1832728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 1842728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<pre> 1852728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<service android:name=".DataLayerListenerService"> 1862728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly <intent-filter> 1872728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly <action android:name="com.google.android.gms.wearable.BIND_LISTENER" /> 1882728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly </intent-filter> 1892728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly</service> 1902728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly</pre> 1912728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 1922728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 1932728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<h4>Permissions within Data Layer Callbacks</h4> 1942728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 195eff209d2c40221d2f9be2fd6b0c9cde51dd5362bRicardo Cervera<p> 196eff209d2c40221d2f9be2fd6b0c9cde51dd5362bRicardo CerveraTo deliver callbacks to your application for data layer events, Google Play services 1972728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lybinds to your <a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"><code>WearableListenerService</code></a>, 1982728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lyand calls your callbacks via IPC. This has the consequence 1992728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lythat your callbacks inherit the permissions of the calling process.</p> 2002728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 2012728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<p>If you try to perform a privileged operation within a callback, the security check fails because your callback is 2022728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lyrunning with the identity of the calling process, instead of the identity of your app's 2032728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lyprocess.</p> 2042728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 2052728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<p>To fix this, call {@link android.os.Binder#clearCallingIdentity} </a>, 2062728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lyto reset identity after crossing the IPC boundary, and then restore identity with 2072728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly{@link android.os.Binder#restoreCallingIdentity restoreCallingIdentity()} when 2082728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lyyou've completed the privileged operation: 2092728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly</p> 2102728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 2112728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<pre> 2122728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lylong token = Binder.clearCallingIdentity(); 2132728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lytry { 2142728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly performOperationRequiringPermissions(); 2152728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly} finally { 2162728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly Binder.restoreCallingIdentity(token); 2172728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly} 2182728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly</pre> 2192728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 2202728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<h3 id="Listen">With a Listener Activity</h3> 2212728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 2222728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<p> 2232728c2a93abd74ef19e550f3530ee70ea41424b3Robert LyIf your app only cares about data layer events when the user is interacting 2242728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lywith the app and does not need a long-running service to handle every data 2252728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lychange, you can listen for events in an activity by implementing one or more 2262728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lyof the following interfaces: 2272728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 2282728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<ul> 2292728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly <li><a href="{@docRoot}reference/com/google/android/gms/wearable/DataApi.DataListener.html"><code>DataApi.DataListener</code></a></li> 2302728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly <li><a href="{@docRoot}reference/com/google/android/gms/wearable/MessageApi.MessageListener.html"><code>MessageApi.MessageListener</code></a></li> 2312728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly <li><a href="{@docRoot}reference/com/google/android/gms/wearable/NodeApi.NodeListener.html"><code>NodeApi.NodeListener</code></a></li> 2322728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly</ul> 2332728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly</p> 2342728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 2352728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<p>To create an activity that listens for data events:</p> 2362728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<ol> 2372728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<li>Implement the desired interfaces.</li> 2382728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<li>In {@link android.app.Activity#onCreate}, create an instance of 2392728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html"><code>GoogleApiClient</code></a> 240eff209d2c40221d2f9be2fd6b0c9cde51dd5362bRicardo Cerverato work with the Data Layer API. 2412728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<li> 2422728c2a93abd74ef19e550f3530ee70ea41424b3Robert LyIn {@link android.app.Activity#onStart onStart()}, call <a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html#connect()"><code>connect()</code></a> to connect the client to Google Play services. 2432728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly</li> 2442728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<li>When the connection to Google Play services is established, the system calls 2452728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)"><code>onConnected()</code></a>. This is where you call 2462728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<a href="{@docRoot}reference/com/google/android/gms/wearable/DataApi.html#addListener(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.wearable.DataApi.DataListener)"><code>DataApi.addListener()</code></a>, 2472728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly <a href="{@docRoot}reference/com/google/android/gms/wearable/MessageApi.html#addListener(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.wearable.MessageApi.MessageListener)"><code>MessageApi.addListener()</code></a>, 2482728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly or <a href="{@docRoot}reference/com/google/android/gms/wearable/NodeApi.html#addListener(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.wearable.NodeApi.NodeListener)"><code>NodeApi.addListener()</code></a> 2492728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly to notify Google Play services that your activity is interested in listening for data layer events. 2502728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly</li> 2512728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<li>In {@link android.app.Activity#onStop onStop()}, unregister any listeners with 2522728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<a href="{@docRoot}reference/com/google/android/gms/wearable/DataApi.html#removeListener(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.wearable.DataApi.DataListener)"><code>DataApi.removeListener()</code></a>, 2532728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<a href="{@docRoot}reference/com/google/android/gms/wearable/MessageApi.html#removeListener(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.wearable.MessageApi.MessageListener)"><code>MessageApi.removeListener()</code></a>, 2542728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lyor <a href="{@docRoot}reference/com/google/android/gms/wearable/NodeApi.html#removeListener(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.wearable.NodeApi.NodeListener)"><code>NodeApi.removeListener()</code></a>. 2552728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly</li> 2562728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<li>Implement <a href="{@docRoot}reference/com/google/android/gms/wearable/DataApi.DataListener.html#onDataChanged(com.google.android.gms.wearable.DataEventBuffer)"><code>onDataChanged()</code>, 2572728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly <a href="{@docRoot}reference/com/google/android/gms/wearable/NodeApi.NodeListener.html#onPeerConnected(com.google.android.gms.wearable.Node)"><code>onMessageReceived()</code></a>, 2582728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly <a href="{@docRoot}reference/com/google/android/gms/wearable/NodeApi.NodeListener.html#onPeerConnected(com.google.android.gms.wearable.Node)"><code>onPeerConnected()</code></a>, and 2592728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly <a href="{@docRoot}reference/com/google/android/gms/wearable/NodeApi.NodeListener.html#onPeerDisconnected(com.google.android.gms.wearable.Node)"><code>onPeerDisconnected()</code></a>, depending on the interfaces that you implemented. 2602728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly</li> 2612728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly</ol> 2622728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 2632728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<p>Here's an example that implements 2642728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<a href="{@docRoot}reference/com/google/android/gms/wearable/DataApi.DataListener.html"><code>DataApi.DataListener</code></a>:</p> 2652728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 2662728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly<pre> 2672728c2a93abd74ef19e550f3530ee70ea41424b3Robert Lypublic class MainActivity extends Activity implements 2682728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly DataApi.DataListener, ConnectionCallbacks, OnConnectionFailedListener { 2692728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 270c2be8a6da0c193a0592586cfc8bdfdb7903cc055Ricardo Cervera private GoogleApiClient mGoogleApiClient; 271c2be8a6da0c193a0592586cfc8bdfdb7903cc055Ricardo Cervera 2722728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly @Override 2732728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly protected void onCreate(Bundle savedInstanceState) { 2742728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly super.onCreate(savedInstanceState); 2752728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 2762728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly setContentView(R.layout.main); 2772728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly mGoogleApiClient = new GoogleApiClient.Builder(this) 2782728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly .addApi(Wearable.API) 2792728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly .addConnectionCallbacks(this) 2802728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly .addOnConnectionFailedListener(this) 2812728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly .build(); 2822728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly } 2832728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 2842728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly @Override 2852728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly protected void onStart() { 2862728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly super.onStart(); 2872728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly if (!mResolvingError) { 2882728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly mGoogleApiClient.connect(); 2892728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly } 2902728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly } 2912728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 292eff209d2c40221d2f9be2fd6b0c9cde51dd5362bRicardo Cervera @Override 2932728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly public void onConnected(Bundle connectionHint) { 2942728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly if (Log.isLoggable(TAG, Log.DEBUG)) { 2952728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly Log.d(TAG, "Connected to Google Api Service"); 2962728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly } 2972728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly Wearable.DataApi.addListener(mGoogleApiClient, this); 2982728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly } 2992728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 3002728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly @Override 3012728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly protected void onStop() { 3022728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly if (null != mGoogleApiClient && mGoogleApiClient.isConnected()) { 3037a04794186dcb679501a7a9383caae8df01428d0Chris Smith Wearable.DataApi.removeListener(mGoogleApiClient, this); 3042728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly mGoogleApiClient.disconnect(); 3052728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly } 3062728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly super.onStop(); 3072728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly } 3082728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly 3092728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly @Override 3102728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly public void onDataChanged(DataEventBuffer dataEvents) { 3112728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly for (DataEvent event : dataEvents) { 3122728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly if (event.getType() == DataEvent.TYPE_DELETED) { 3132728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly Log.d(TAG, "DataItem deleted: " + event.getDataItem().getUri()); 3142728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly } else if (event.getType() == DataEvent.TYPE_CHANGED) { 315eff209d2c40221d2f9be2fd6b0c9cde51dd5362bRicardo Cervera Log.d(TAG, "DataItem changed: " + event.getDataItem().getUri()); 3162728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly } 3172728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly } 3182728c2a93abd74ef19e550f3530ee70ea41424b3Robert Ly } 319c2be8a6da0c193a0592586cfc8bdfdb7903cc055Ricardo Cervera} 320eff209d2c40221d2f9be2fd6b0c9cde51dd5362bRicardo Cervera</pre> 321