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<resources> 85 <string-array name="android_wear_capabilities"> 86 <item>voice_transcription</item> 87 </string-array> 88</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 @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<Node> connectedNodes = capabilityInfo.getNodes(); 167 168 transcriptionNodeId = pickBestNodeId(connectedNodes); 169} 170 171private String pickBestNodeId(Set<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 @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<String> getNodes() { 237 HashSet <String>results = new HashSet<String>(); 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@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>