• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=Sending and Receiving Messages
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="#SendMessage">Send a Message</a></li>
11  <li><a href="#ReceiveMessage">Receive a Message</a></li>
12</ol>
13</div>
14</div>
15
16<p>You send messages using the
17<a href="{@docRoot}reference/com/google/android/gms/wearable/MessageApi.html"><code>MessageApi</code></a>
18and attach the following items to the message:</p>
19
20<ul>
21  <li>An arbitrary payload (optional)</li>
22  <li>A path that uniquely identifies the message's action</li>
23</ul>
24
25<p>
26Unlike with data items, there is no syncing between the handheld and wearable apps.
27Messages are a one-way communication mechanism that's good for remote procedure calls (RPC),
28such as sending a message to the wearable to start an activity.</p>
29
30<p>Multiple wearable devices can be connected to a user’s handheld device. Each connected device in
31the network is considered a <em>node</em>. With multiple connected devices, you must consider which
32nodes receive the messages. For example, in a voice transcription app that receives voice data on
33the wearable device, you should send the message to a node with the processing power and battery
34capacity to handle the request, such as a handheld device.</p>
35
36<p class="note"><strong>Note:</strong>
37With versions of Google Play services prior to 7.3.0, only one wearable device could be connected to
38a handheld device at a time. You may need to update your existing code to take the multiple
39connected nodes feature into consideration. If you don’t implement the changes, your messages may
40not get delivered to intended devices.
41</p>
42
43<h2 id="SendMessage">Send a Message</h2>
44
45<p>A wearable app can provide functionality for users such as voice
46transcription. Users can speak into their wearable device's microphone, and have a transcription
47saved to a note. Since a wearable device typically does not have the processing power and battery
48capacity required to handle the voice transcription activity, the app should offload this work to a
49more capable, connected device.</p>
50
51<p>The following sections show you how to advertise device nodes that can process activity
52requests, discover the nodes capable of fulfilling a requested need, and send messages to those
53nodes.
54</p>
55
56<h3 id="AdvertiseCapabilities">Advertise capabilities</h3>
57
58<p>To launch an activity on a handheld device from a wearable device, use the
59<a href="{@docRoot}reference/com/google/android/gms/wearable/MessageApi.html"><code>MessageApi</code></a>
60class to send the request. Since multiple wearables can be connected to the handheld device, the
61wearable app needs to determine that a connected node is capable of launching the activity. In your
62handheld app, advertise that the node it runs on provides specific capabilities.</p>
63
64<p>To advertise the capabilities of your handheld app:</p>
65
66<ol>
67  <li>Create an XML configuration file in the <code>res/values/</code> directory of your project and
68  name it <code>wear.xml</code>.
69  </li>
70  <li>Add a resource named <code>android_wear_capabilities</code> to <code>wear.xml</code>.
71  </li>
72  <li>Define capabilities that the device provides.
73  </li>
74</ol>
75
76<p class="note"><strong>Note:</strong>
77Capabilities are custom strings that you define and must be unique within your app.
78</p>
79
80<p>The following example shows how to add a capability named <code>voice_transcription</code> to
81<code>wear.xml</code>:</p>
82
83<pre>
84&lt;resources>
85    &lt;string-array name="android_wear_capabilities">
86        &lt;item>voice_transcription&lt;/item>
87    &lt;/string-array>
88&lt;/resources>
89</pre>
90
91<h3 id="RetrieveCapabilities">Retrieve the nodes with the required capabilities</h3>
92
93<p>Initially, you can detect the capable nodes by calling the <a
94href="{@docRoot}reference/com/google/android/gms/wearable/CapabilityApi.html#getCapability(com.google.android.gms.common.api.GoogleApiClient, java.lang.String, int)"><code>CapabilityApi.getCapability()</code></a>
95method.
96The following example shows how to manually retrieve the results of reachable nodes with the
97<code>voice_transcription</code> capability:</p>
98
99<pre>
100private static final String
101        VOICE_TRANSCRIPTION_CAPABILITY_NAME = "voice_transcription";
102
103private GoogleApiClient mGoogleApiClient;
104
105...
106
107private void setupVoiceTranscription() {
108    CapabilityApi.GetCapabilityResult result =
109            Wearable.CapabilityApi.getCapability(
110                    mGoogleApiClient, VOICE_TRANSCRIPTION_CAPABILITY_NAME,
111                    CapabilityApi.FILTER_REACHABLE).await();
112
113    updateTranscriptionCapability(result.getCapability());
114}
115</pre>
116
117<p>To detect capable nodes as they connect to the wearable device, register a <a
118href="{@docRoot}reference/com/google/android/gms/wearable/CapabilityApi.CapabilityListener.html"><code>CapabilityApi.CapabilityListener()</code></a>
119instance to your <a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html"><code>GoogleApiClient</code></a>.
120The following example shows how to register the listener and retrieve the results of reachable nodes
121with the <code>voice_transcription</code> capability:</p>
122
123<pre>
124private void setupVoiceTranscription() {
125    ...
126
127    CapabilityApi.CapabilityListener capabilityListener =
128            new CapabilityApi.CapabilityListener() {
129                &#64;Override
130                public void onCapabilityChanged(CapabilityInfo capabilityInfo) {
131                    updateTranscriptionCapability(capabilityInfo);
132                }
133            };
134
135    Wearable.CapabilityApi.addCapabilityListener(
136            mGoogleApiClient,
137            capabilityListener,
138            VOICE_TRANSCRIPTION_CAPABILITY_NAME);
139}
140</pre>
141
142<p class="note"><strong>Note:</strong>
143If you create a service that extends
144<a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"><code>WearableListenerService</code></a>
145to detect capability changes, you may want to override the
146<a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html#onConnectedNodes(java.util.List<com.google.android.gms.wearable.Node>)"><code>onConnectedNodes()</code></a>
147method to listen to finer-grained connectivity details, such as when a wearable
148device switches from Wi-Fi to a Bluetooth connection to the handset.
149For more information on how to listen for important events, see
150<a href="{@docRoot}training/wearables/data-layer/events.html#Listen">Listen for Data Layer Events</a>.
151</p>
152
153<p>After detecting the capable nodes, determine where to send the message. You should pick a node
154that is in close proximity to your wearable device to
155minimize message routing through multiple nodes. A nearby node is defined as one that is directly
156connected to the device. To determine if a node is nearby, call the <a
157href="{@docRoot}reference/com/google/android/gms/wearable/Node.html#isNearby()"><code>Node.isNearby()</code></a>
158method.</p>
159
160<p>The following example shows how you might determine the best node to use:</p>
161
162<pre>
163private String transcriptionNodeId = null;
164
165private void updateTranscriptionCapability(CapabilityInfo capabilityInfo) {
166    Set&lt;Node> connectedNodes = capabilityInfo.getNodes();
167
168    transcriptionNodeId = pickBestNodeId(connectedNodes);
169}
170
171private String pickBestNodeId(Set&lt;Node> nodes) {
172    String bestNodeId = null;
173    // Find a nearby node or pick one arbitrarily
174    for (Node node : nodes) {
175        if (node.isNearby()) {
176            return node.getId();
177         }
178         bestNodeId = node.getId();
179    }
180    return bestNodeId;
181}
182</pre>
183
184<h3 id="DeliverMessage">Deliver the message</h3>
185
186<p>Once you’ve identified the best node to use, send the message using the
187<a href="{@docRoot}reference/com/google/android/gms/wearable/MessageApi.html"><code>MessageApi</code></a>
188class.</p>
189
190<p>The following example shows how to send a message to the transcription-capable node from a
191wearable device. Verify that the node is available before you attempt to send the message. This call
192is synchronous and blocks processing until the system queues the message for delivery.
193</p>
194
195<p class="note"><strong>Note:</strong> A successful result code does not guarantee delivery of the
196message. If your app requires data reliability, use
197<a href="{@docRoot}reference/com/google/android/gms/wearable/DataItem.html"><code>DataItem</code></a>
198objects or the
199<a href="{@docRoot}reference/com/google/android/gms/wearable/ChannelApi.html"><code>ChannelApi</code></a>
200class to send data between devices.
201</p>
202
203<pre>
204
205public static final String VOICE_TRANSCRIPTION_MESSAGE_PATH = "/voice_transcription";
206
207private void requestTranscription(byte[] voiceData) {
208    if (transcriptionNodeId != null) {
209        Wearable.MessageApi.sendMessage(googleApiClient, transcriptionNodeId,
210            VOICE_TRANSCRIPTION_MESSAGE_PATH, voiceData).setResultCallback(
211                  new ResultCallback<SendMessageResult>() {
212                      &#64;Override
213                      public void onResult(SendMessageResult sendMessageResult) {
214                          if (!sendMessageResult.getStatus().isSuccess()) {
215                              // Failed to send message
216                          }
217                      }
218                  }
219            );
220    } else {
221        // Unable to retrieve node with transcription capability
222    }
223}
224</pre>
225
226<p class="note"><strong>Note:</strong> To learn more about asynchronous and synchronous calls
227to Google Play services and when to use each, see
228<a href="{@docRoot}google/auth/api-client.html#Communicating">Communicate with Google Play
229Services</a>.
230</p>
231
232<p>You can also broadcast messages to all connected nodes. To retrieve all of the
233connected nodes that you can send messages to, implement the following code:</p>
234
235<pre>
236private Collection&lt;String&gt; getNodes() {
237    HashSet &lt;String&gt;results = new HashSet&lt;String&gt;();
238    NodeApi.GetConnectedNodesResult nodes =
239            Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();
240    for (Node node : nodes.getNodes()) {
241        results.add(node.getId());
242    }
243    return results;
244}
245</pre>
246
247<h2 id="ReceiveMessage">Receive a Message</h2>
248
249<p>
250To be notified of received messages, implement the
251<a href="{@docRoot}reference/com/google/android/gms/wearable/MessageApi.MessageListener.html">
252<code>MessageListener</code></a> interface to provide a listener for message events. Then,
253register the listener with the
254<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)">
255<code>MessageApi.addListener()</code></a> method. This example shows how you might implement the
256listener to check the <code>VOICE_TRANSCRIPTION_MESSAGE_PATH</code>. If this condition is
257<code>true</code>, start an activity to process the voice
258data.
259</p>
260
261<pre>
262&#64;Override
263public void onMessageReceived(MessageEvent messageEvent) {
264    if (messageEvent.getPath().equals(VOICE_TRANSCRIPTION_MESSAGE_PATH)) {
265        Intent startIntent = new Intent(this, MainActivity.class);
266        startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
267        startIntent.putExtra("VOICE_DATA", messageEvent.getData());
268        startActivity(startIntent);
269    }
270}
271</pre>
272
273<p>
274This is just a snippet that requires more implementation details. Learn about
275how to implement a full listener service or activity in
276<a href="{@docRoot}training/wearables/data-layer/events.html#Listen">Listening for Data Layer
277Events</a>.
278</p>