diff options
| -rw-r--r-- | docs/html/training/wearables/data-layer/events.jd | 302 |
1 files changed, 200 insertions, 102 deletions
diff --git a/docs/html/training/wearables/data-layer/events.jd b/docs/html/training/wearables/data-layer/events.jd index c797f6882fff..9bed9d548aad 100644 --- a/docs/html/training/wearables/data-layer/events.jd +++ b/docs/html/training/wearables/data-layer/events.jd @@ -68,72 +68,100 @@ if(result.getStatus().isSuccess()) { </pre> -<h2 id="Listen">Listen for Data Layer Events </h2> -<p>Because the data layer synchronizes and sends data across the handheld and -wearable, you normally want to listen for important events, such as when data items -are created, messages are received, or when the wearable and handset are connected. +<h2 id="Listen">Listen for Data Layer Events</h2> +<p> +Because the data layer synchronizes and sends data across the handheld and +wearable, it is usually necessary to listen for important events. Examples of +such events include creation of data items and receipt of messages. +</p> +<p> +To listen for data layer events, you have two options: </p> -<p>To listen for data layer events, you have two options:</p> - <ul> - <li>Create a service that extends - <a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"><code>WearableListenerService</code></a>. - </li> - <li>Create an activity that implements - <a href="{@docRoot}reference/com/google/android/gms/wearable/DataApi.DataListener.html"><code>DataApi.DataListener</code></a>. - </li> + <li>Create a service that extends <a href +="https://developer.android.com/reference/com/google/android/gms/wearable/WearableListenerService.html"> +{@code WearableListenerService}</a>.</li> + <li>Create an activity that implements <a +href="https://developer.android.com/reference/com/google/android/gms/wearable/DataApi.DataListener.html"> +{@code DataApi.DataListener}</a>.</li> </ul> - -<p>With both these options, you override the data event callback methods for the events you -are interested in handling.</p> - -<h3 id="listener-service">With a WearableListenerService</h3> - <p> -You typically create instances of this service in both your wearable and handheld apps. If you -are not interested in data events in one of these apps, then you don't need to implement this -service in that particular app.</p> - -<p>For example, you can have a handheld app that sets and gets data item objects and a wearable app -that listens for these updates to update it's UI. The wearable never updates any of the data items, -so the handheld app doesn't listen for any data events from the wearable app.</p> - -<p>You can listen for the following events with -<a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"><code>WearableListenerService</code></a>:</p> - +With both these options, you override the data event callback methods for the +events you are interested in handling. +</p> +<h3>With a WearableListenerService</h3> +<p> +You typically create instances of this service in both your wearable and +handheld apps. If you are not interested in data events in one of these apps, +then you don't need to implement this service in that particular app. +</p> +<p> +For example, you can have a handheld app that sets and gets data item objects +and a wearable app that listens for these updates to update its UI. The +wearable never updates any of the data items, so the handheld app doesn't +listen for any data events from the wearable app. +</p> +<p> +Some of the events you can listen for using <a +href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"> +{@code WearableListenerService}</a> are as follows: +</p> <ul> - <li><a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html#onDataChanged(com.google.android.gms.wearable.DataEventBuffer)"><code>onDataChanged()</code></a> -- Called when data item objects are created, changed, or deleted. An event on one side of a connection -triggers this callback on both sides.</li> - <li><a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html#onMessageReceived(com.google.android.gms.wearable.MessageEvent)"><code>onMessageReceived()</code></a> -- A message sent from one side of a connection triggers this callback on the other side of the connection.</li> - <li><a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html#onMessageReceived(com.google.android.gms.wearable.MessageEvent)"><code>onPeerConnected()</code></a> - and <a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html#onPeerDisconnected(com.google.android.gms.wearable.Node)"><code>onPeerDisconnected()</code></a> - - Called when the connection with the handheld or wearable is connected or disconnected. - Changes in connection state on one side of the connection trigger these callbacks on both sides - of the connection. - </li> -</ul> + <li><a +href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html#onDataChanged(com.google.android.gms.wearable.DataEventBuffer)"> +{@code onDataChanged()}</a>: +Whenever a data item object is created, deleted, or changed, the system triggers +this callback on all connected nodes. +</li> +<li><a +href="http://developer.android.com/reference/com/google/android/gms/wearable/WearableListenerService.html#onMessageReceived(com.google.android.gms.wearable.MessageEvent)"> +{@code onMessageReceived()}</a>: A message sent from a node triggers +this callback on the target node.</li> +<li><a +href="https://developers.google.com/android/reference/com/google/android/gms/wearable/WearableListenerService.html#onCapabilityChanged(com.google.android.gms.wearable.CapabilityInfo)"> +{@code onCapabilityChanged()}</a>: +When a capability that an instance of your app advertises becomes available +on the network, that event triggers this callback. If you're looking for a +nearby node you can query the +<a +href="https://developers.google.com/android/reference/com/google/android/gms/wearable/Node.html#isNearby()"> +{@code isNearby()}</a> method of the nodes provided in the callback.</li> -<p>To create a <a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"><code>WearableListenerService</code></a>:</p> +<p> +In addition to those on this list, you can listen for events from +<a href="https://developers.google.com/android/reference/com/google/android/gms/wearable/ChannelApi.ChannelListener"> +{@code ChannelApi.ChannelListener}</a>, such as +<a href="https://developers.google.com/android/reference/com/google/android/gms/wearable/ChannelApi.ChannelListener.html#onChannelOpened(com.google.android.gms.wearable.Channel)"> +{@code onChannelOpened()}</a>. +</p> +</ul> +<p>To create a <a +href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"><code>WearableListenerService</code></a>, follow these steps:</p> <ol> <li>Create a class that extends - <a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"><code>WearableListenerService</code></a>. + <a +href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"><code>WearableListenerService</code></a>. </li> <li>Listen for the events that you're interested in, such as - <a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html#onDataChanged(com.google.android.gms.wearable.DataEventBuffer)"><code>onDataChanged()</code></a>. + <a +href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html#onDataChanged(com.google.android.gms.wearable.DataEventBuffer)"> +<code>onDataChanged()</code></a>. </li> - <li>Declare an intent filter in your Android manifest to notify the system about your - <a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"><code>WearableListenerService</code></a>. - This allows the system to bind your service as needed. + <li>Declare an intent filter in your Android manifest to notify the system +about your + <a +href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"><code> +WearableListenerService</code></a>. + This declaration allows the system to bind your service as needed. </li> </ol> <p>The following example shows how to implement a simple - <a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"><code>WearableListenerService</code></a>: + <a +href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"><code> +WearableListenerService</code></a>: </p> - <pre> public class DataLayerListenerService extends WearableListenerService { @@ -146,7 +174,7 @@ public class DataLayerListenerService extends WearableListenerService { if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "onDataChanged: " + dataEvents); } - final List<DataEvent> events = FreezableUtils + final List events = FreezableUtils .freezeIterable(dataEvents); GoogleApiClient googleApiClient = new GoogleApiClient.Builder(this) @@ -179,85 +207,139 @@ public class DataLayerListenerService extends WearableListenerService { } </pre> -<p>Here's the corresponding intent filter in the Android manifest file:</p> +<p> +The next section explains how to use an intent filter with this listener. +</p> + +<h3>Using filters with WearableListenerService</h3> + +<p> +An intent filter for the +<a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"> +{@code WearableListenerService}</a> example shown in the previous section might look like this: <pre> <service android:name=".DataLayerListenerService"> - <intent-filter> - <action android:name="com.google.android.gms.wearable.BIND_LISTENER" /> + <intent-filter> + <action android:name="com.google.android.gms.wearable.DATA_CHANGED" /> + <data android:scheme="wear" android:host="*" + android:path="/start-activity" /> </intent-filter> </service> </pre> - -<h4>Permissions within Data Layer Callbacks</h4> - <p> -To deliver callbacks to your application for data layer events, Google Play services -binds to your <a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"><code>WearableListenerService</code></a>, -and calls your callbacks via IPC. This has the consequence -that your callbacks inherit the permissions of the calling process.</p> - -<p>If you try to perform a privileged operation within a callback, the security check fails because your callback is -running with the identity of the calling process, instead of the identity of your app's -process.</p> - -<p>To fix this, call {@link android.os.Binder#clearCallingIdentity} </a>, -to reset identity after crossing the IPC boundary, and then restore identity with -{@link android.os.Binder#restoreCallingIdentity restoreCallingIdentity()} when -you've completed the privileged operation: +In this filter, the {@code DATA_CHANGED} action replaces the +previously recommended {@code BIND_LISTENER} action so that only specific +events wake or launch your application. This change improves system efficiency +and reduces battery consumption and other overhead associated with your +application. In this example, the watch listens for the +{@code /start-activity} data item, and the +phone listens for the {@code /data-item-received} message response. +</p> +<p> +Standard Android filter matching rules apply. You can specify multiple services +per manifest, multiple intent filters per service, multiple actions per filter, +and multiple data stanzas per filter. Filters can match on a wildcard host or on +a specific one. To match on a wildcard host, use {@code host="*"}. To match +on a specific host, specify {@code host=<node_id>}. </p> -<pre> -long token = Binder.clearCallingIdentity(); -try { - performOperationRequiringPermissions(); -} finally { - Binder.restoreCallingIdentity(token); -} -</pre> +<p> +You can also match a literal path or path prefix. If you are matching by path +or path prefix, you must specify a wildcard or specific host. +If you do not do so, the system ignores the path you specified. +</p> +<p> +For more information on the filter types that Wear supports, see the +API reference documentation for <a +href="https://developers.google.com/android/reference/com/google/android/gms/wearable/WearableListenerService"> +{@code WearableListenerService}</a>. -<h3 id="Listen">With a Listener Activity</h3> +</p> <p> -If your app only cares about data layer events when the user is interacting -with the app and does not need a long-running service to handle every data -change, you can listen for events in an activity by implementing one or more -of the following interfaces: +For more information on data filters and matching rules, see the API reference +documentation for the <a +href="{@docRoot}guide/topics/manifest/data-element.html">{@code data}</a> +manifest element. +</p> + +<p>When matching intent filters, there are two important rules to remember:</p> <ul> - <li><a href="{@docRoot}reference/com/google/android/gms/wearable/DataApi.DataListener.html"><code>DataApi.DataListener</code></a></li> - <li><a href="{@docRoot}reference/com/google/android/gms/wearable/MessageApi.MessageListener.html"><code>MessageApi.MessageListener</code></a></li> - <li><a href="{@docRoot}reference/com/google/android/gms/wearable/NodeApi.NodeListener.html"><code>NodeApi.NodeListener</code></a></li> + <li>If a scheme is not specified for the intent filter, the system ignores + all the other URI attributes.</li> + <li>If no host is specified for the filter, the system ignores the + port attribute and all the path attributes.</li> </ul> + +<h3>With a listener activity</h3> +<p> +If your app only cares about data-layer events when the user is interacting +with the app, it may not need a long-running service to handle every data +change. In such a case, you can listen for events in an activity by +implementing one or more of the following interfaces: </p> +<ul> + <li><a href="{@docRoot}reference/com/google/android/gms/wearable/DataApi.DataListener.html"><code> + DataApi.DataListener</code></a></li> + + <li><a href="{@docRoot}reference/com/google/android/gms/wearable/MessageApi.MessageListener.html"> + <code>MessageApi.MessageListener</code></a></li> + + <li><a href="https://developers.google.com/android/reference/com/google/android/gms/wearable/CapabilityApi.CapabilityListener.html">{@code CapabilityApi.CapabilityListener}</a></li> +</ul> <p>To create an activity that listens for data events:</p> <ol> <li>Implement the desired interfaces.</li> -<li>In {@link android.app.Activity#onCreate}, create an instance of -<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html"><code>GoogleApiClient</code></a> -to work with the Data Layer API. +<li>In {@link android.app.Activity#onCreate onCreate()}, create an instance of +<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html"><code>GoogleApiClient</code> +</a>to work with the Data Layer API.</li> + <li> -In {@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. +In {@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. </li> + <li>When the connection to Google Play services is established, the system calls <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 -<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>, - <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>, - 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> - to notify Google Play services that your activity is interested in listening for data layer events. -</li> + +<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>, + +<a href="{@docRoot}android/reference/com/google/android/gms/wearable/CapabilityApi.CapabilityListener"> +<code>MessageApi.addListener()</code></a>, or + +<a href="https://developers.google.com/android/reference/com/google/android/gms/wearable/CapabilityApi.html#addListener(com.google.android.gms.common.api.GoogleApiClient,%20com.google.android.gms.wearable.CapabilityApi.CapabilityListener,%20android.net.Uri,%20int)"> +{@code CapabilityApi.addListener()}</a> to notify Google Play services that your activity is +interested in listening for data layer events.</li> + <li>In {@link android.app.Activity#onStop onStop()}, unregister any listeners with <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>, -<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>, -or <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>. -</li> -<li>Implement <a href="{@docRoot}reference/com/google/android/gms/wearable/DataApi.DataListener.html#onDataChanged(com.google.android.gms.wearable.DataEventBuffer)"><code>onDataChanged()</code>, - <a href="{@docRoot}reference/com/google/android/gms/wearable/NodeApi.NodeListener.html#onPeerConnected(com.google.android.gms.wearable.Node)"><code>onMessageReceived()</code></a>, - <a href="{@docRoot}reference/com/google/android/gms/wearable/NodeApi.NodeListener.html#onPeerConnected(com.google.android.gms.wearable.Node)"><code>onPeerConnected()</code></a>, and - <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. -</li> +<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>, or +<a href="http://developer.android.com/reference/com/google/android/gms/wearable/MessageApi.html#removeListener(com.google.android.gms.common.api.GoogleApiClient,%20com.google.android.gms.wearable.MessageApi.MessageListener)"> +{@code CapabilityApi.removeListener()}</a>.</li> + + +<p>An alternative to adding listeners in +<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)"><code>onConnected()</code></a> +and removing them in +{@link android.app.Activity#onStop onStop()} is to add a filtered listener in an activity’s {@link android.app.Activity#onResume onResume()} and +remove it in {@link android.app.Activity#onPause onPause()}, so as to only receive data that is relevant to the +current application state.</p> + + +<li>Implement +<a href="{@docRoot}reference/com/google/android/gms/wearable/DataApi.DataListener.html#onDataChanged(com.google.android.gms.wearable.DataEventBuffer)"> +<code>onDataChanged()</code></a>, + <a href="https://developers.google.com/android/reference/com/google/android/gms/wearable/MessageApi.MessageListener.html#onMessageReceived(com.google.android.gms.wearable.MessageEvent)"> + <code>onMessageReceived()</code></a>, + <a href="https://developers.google.com/android/reference/com/google/android/gms/wearable/WearableListenerService.html#onCapabilityChanged(com.google.android.gms.wearable.CapabilityInfo)"> +{@code onCapabilityChanged()}</a>, +or methods from <a href="http://developer.android.com/reference/com/google/android/gms/wearable/ChannelApi.ChannelListener.html"> +Channel API listener methods</a>, depending on the interfaces that you implemented.</li> </ol> <p>Here's an example that implements @@ -318,3 +400,19 @@ public class MainActivity extends Activity implements } } </pre> +<h3>Using Filters with Listener Activities</h3> +<p> +Just as you can specify intent filters for manifest-based +<a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"> +<code>WearableListenerService</code></a> objects, you can also use intent filters when registering a +listener through the Wearable API. The same rules are applicable to both +API-based listeners manifest-based listeners. +</p> + +<p> +A common pattern is to register a listener with a specific path or path prefix +in an activity’s{@link android.app.Activity#onResume onResume()} method, and to +remove the listener in the activity’s {@link android.app.Activity#onPause onPause()} method. +Implementing listeners in this fashion allows your application to more selectively receive events, +improving its design and efficiency. +</p> |