| page.title=Sending and Receiving Messages |
| |
| @jd:body |
| |
| <div id="tb-wrapper"> |
| <div id="tb"> |
| |
| <h2>This lesson teaches you to</h2> |
| <ol> |
| <li><a href="#SendMessage">Send a Message</a></li> |
| <li><a href="#ReceiveMessage">Receive a Message</a></li> |
| </ol> |
| </div> |
| </div> |
| |
| <p>You send messages using the |
| <a href="{@docRoot}reference/com/google/android/gms/wearable/MessageApi.html"><code>MessageApi</code></a> |
| and attach the following items to the message:</p> |
| |
| <ul> |
| <li>An arbitrary payload (optional)</li> |
| <li>A path that uniquely identifies the message's action</li> |
| </ul> |
| <p> |
| Unlike with data items, there is no syncing between the handheld and wearable apps. |
| Messages are a one-way communication mechanism that's good for remote procedure calls (RPC), |
| such as sending a message to the wearable to start an activity.</p> |
| |
| <p>Multiple wearable devices can be connected to a user’s handheld device. Each connected device in |
| the network is considered a <em>node</em>. With multiple connected devices, you must consider which |
| nodes receive the messages. For example, In a voice transcription app that receives voice data on |
| the wearable device, you should send the message to a node with the processing power and battery |
| capacity to handle the request, such as a handheld device.</p> |
| |
| <p class="note"><strong>Note:</strong> |
| With versions of Google Play services prior to 7.3.0, only one wearable device could be connected to |
| a handheld device at a time. You may need to update your existing code to take the multiple |
| connected nodes feature into consideration. If you don’t implement the changes, your messages may |
| not get delivered to intended devices. |
| </p> |
| |
| <h2 id="SendMessage">Send a Message</h2> |
| |
| <p>A wearable app can provide functionality for users such as voice |
| transcription. Users can speak into their wearable device's microphone, and have a transcription |
| saved to a note. Since a wearable device typically does not have the processing power and battery |
| capacity required to handle the voice transcription activity, the app should offload this work to a |
| more capable, connected device.</p> |
| |
| <p>The following sections show you how to advertise device nodes that can process activity |
| requests, discover the nodes capable of fulfilling a requested need, and send messages to those |
| nodes. |
| </p> |
| |
| <h3 id="AdvertiseCapabilities">Advertise capabilities</h3> |
| |
| <p>To launch an activity on a handheld device from a wearable device, use the |
| <a href="{@docRoot}reference/com/google/android/gms/wearable/MessageApi.html"><code>MessageApi</code></a> |
| class to send the request. Since multiple wearables can be connected to the handheld device, the |
| wearable app needs to determine that a connected node is capable of launching the activity. In your |
| handheld app, advertise that the node it runs on provides specific capabilities.</p> |
| |
| <p>To advertise the capabilities of your handheld app:</p> |
| |
| <ol> |
| <li>Create an XML configuration file in the <code>res/values/</code> directory of your project and |
| name it <code>wear.xml</code>. |
| </li> |
| <li>Add a resource named <code>android_wear_capabilities</code> to <code>wear.xml</code>. |
| </li> |
| <li>Define capabilities that the device provides. |
| </li> |
| </ol> |
| |
| <p class="note"><strong>Note:</strong> |
| Capabilities are custom strings that you define and must be unique within your app. |
| </p> |
| |
| <p>The following example shows how to add a capability named <code>voice_transcription</code> to |
| <code>wear.xml</code>:</p> |
| |
| <pre> |
| <resources> |
| <string-array name="android_wear_capabilities"> |
| <item>voice_transcription</item> |
| </string-array> |
| </resources> |
| </pre> |
| |
| <h3 id="RetrieveCapabilities">Retrieve the nodes with the required capabilities</h3> |
| |
| <p>Initially, you can detect the capable nodes by calling the <a |
| href="{@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> |
| method. |
| The following example shows how to manually retrieve the results of reachable nodes with the |
| <code>voice_transcription</code> capability:</p> |
| |
| <pre> |
| private static final String |
| VOICE_TRANSCRIPTION_CAPABILITY_NAME = "voice_transcription"; |
| |
| private GoogleApiClient mGoogleApiClient; |
| |
| ... |
| |
| private void setupVoiceTranscription() { |
| CapabilityApi.GetCapabilityResult result = |
| Wearable.CapabilityApi.getCapability( |
| mGoogleApiClient, VOICE_TRANSCRIPTION_CAPABILITY_NAME, |
| CapabilityApi.FILTER_REACHABLE).await(); |
| |
| updateTranscriptionCapability(result.getCapability()); |
| } |
| </pre> |
| |
| <p>To detect capable nodes as they connect to the wearable device, register a <a |
| href="{@docRoot}reference/com/google/android/gms/wearable/CapabilityApi.CapabilityListener.html"><code>CapabilityApi.CapabilityListener()</code></a> |
| instance to your <a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html"><code>GoogleApiClient</code></a>. |
| The following example shows how to register the listener and retrieve the results of reachable nodes |
| with the <code>voice_transcription</code> capability:</p> |
| |
| <pre> |
| private void setupVoiceTranscription() { |
| ... |
| |
| CapabilityApi.CapabilityListener capabilityListener = |
| new CapabilityApi.CapabilityListener() { |
| @Override |
| public void onCapabilityChanged(CapabilityInfo capabilityInfo) { |
| updateTranscriptionCapability(capabilityInfo); |
| } |
| }; |
| |
| Wearable.CapabilityApi.addCapabilityListener( |
| mGoogleApiClient, |
| capabilityListener, |
| VOICE_TRANSCRIPTION_CAPABILITY_NAME); |
| } |
| </pre> |
| |
| <p>After detecting the capable nodes, determine where to send the message. You should pick a node |
| that is in close proximity to your wearable device to |
| minimize message routing through multiple nodes. A nearby node is defined as one that is directly |
| connected to the device. To determine if a node is nearby, call the <a |
| href="{@docRoot}reference/com/google/android/gms/wearable/Node.html#isNearby()"><code>Node.isNearby()</code></a> |
| method.</p> |
| |
| <p>The following example shows how you might determine the best node to use:</p> |
| |
| <pre> |
| private String transcriptionNodeId = null; |
| |
| private void updateTranscriptionCapability(CapabilityInfo capabilityInfo) { |
| Set<Node> connectedNodes = capabilityInfo.getNodes(); |
| |
| transcriptionNodeId = pickBestNodeId(connectedNodes); |
| } |
| |
| private String pickBestNodeId(Set<Node> nodes) { |
| String bestNodeId = null; |
| // Find a nearby node or pick one arbitrarily |
| for (Node node : nodes) { |
| if (node.isNearby()) { |
| return node.getId(); |
| } |
| bestNodeId = node.getId(); |
| } |
| return bestNodeId; |
| } |
| </pre> |
| |
| <h3 id="DeliverMessage">Deliver the message</h3> |
| |
| <p>Once you’ve identified the best node to use, send the message using the |
| <a href="{@docRoot}reference/com/google/android/gms/wearable/MessageApi.html"><code>MessageApi</code></a> |
| class.</p> |
| |
| <p>The following example shows how to send a message to the transcription-capable node from a |
| wearable device. Verify that the node is available before you attempt to send the message. This call |
| is synchronous and blocks processing until the message is received or until the request times out. |
| </p> |
| |
| <pre> |
| |
| public static final String VOICE_TRANSCRIPTION_MESSAGE_PATH = "/voice_transcription"; |
| |
| private void requestTranscription(byte[] voiceData) { |
| if (transcriptionNodeId != null) { |
| Wearable.MessageApi.sendMessage(googleApiClient, transcriptionNodeId, |
| VOICE_TRANSCRIPTION_MESSAGE_PATH, voiceData).setResultCallback( |
| new ResultCallback<SendMessageResult>() { |
| @Override |
| public void onResult(SendMessageResult sendMessageResult) { |
| if (!sendMessageResult.getStatus().isSuccess()) { |
| // Failed to send message |
| } |
| } |
| } |
| ); |
| } else { |
| // Unable to retrieve node with transcription capability |
| } |
| } |
| </pre> |
| |
| <p class="note"><strong>Note:</strong> To learn more about asynchronous and synchronous calls |
| to Google Play services and when to use each, see |
| <a href="{@docRoot}google/auth/api-client.html#Communicating">Communicate with Google Play |
| Services</a>. |
| </p> |
| |
| <p>You can also broadcast messages to all connected nodes. To retrieve all of the |
| connected nodes that you can send messages to, implement the following code:</p> |
| |
| <pre> |
| private Collection<String> getNodes() { |
| HashSet <String>results = new HashSet<String>(); |
| NodeApi.GetConnectedNodesResult nodes = |
| Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await(); |
| for (Node node : nodes.getNodes()) { |
| results.add(node.getId()); |
| } |
| return results; |
| } |
| </pre> |
| |
| <h2 id="ReceiveMessage">Receive a Message</h2> |
| |
| <p> |
| To be notified of received messages, implement the |
| <a href="{@docRoot}reference/com/google/android/gms/wearable/MessageApi.MessageListener.html"> |
| <code>MessageListener</code></a> interface to provide a listener for message events. Then, |
| register the listener with the |
| <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> method. This example shows how you might implement the |
| listener to check the <code>VOICE_TRANSCRIPTION_MESSAGE_PATH</code>. If this condition is |
| <code>true</code>, start an activity to process the voice |
| data. |
| </p> |
| |
| <pre> |
| @Override |
| public void onMessageReceived(MessageEvent messageEvent) { |
| if (messageEvent.getPath().equals(VOICE_TRANSCRIPTION_MESSAGE_PATH)) { |
| Intent startIntent = new Intent(this, MainActivity.class); |
| startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
| startIntent.putExtra("VOICE_DATA", messageEvent.getData()); |
| startActivity(startIntent); |
| } |
| } |
| </pre> |
| |
| <p> |
| This is just a snippet that requires more implementation details. Learn about |
| how to implement a full listener service or activity in |
| <a href="{@docRoot}training/wearables/data-layer/events.html#Listen">Listening for Data Layer |
| Events</a>. |
| </p> |