original source : https://developer.android.com/training/wearables/data-layer/messages.html

Sending and Receiving Messages

You send messages using the MessageApi and attach the following items to the message:

  • An arbitrary payload (optional)
  • A path that uniquely identifies the message’s action

syncing 은 양방향이라면 message는 일방이며 

remote procedure calls (RPC)에 유용하다. 예를 들어 sending a message to the wearable to start an activity.

Multiple wearable devices can be connected to a user’s handheld device. Each connected device in the network is considered a node. 그러므로 message를 보내는 경우 목적지를 명확하게 해야 한다. google play 7.3 이전에는 하나의 mobile에 하나의 wearable기기만 연결할수 있으나 그 이후 버전에는 여러개를 연결해서 사용가능하므로 새로운 기능에대한 업데이트를 잘못하면 제대로 전달되지 않는 문제가 발생할수 있다.

Send a Message

       

Advertise capabilities

To launch an activity on a handheld device from a wearable device, use the MessageApi class to send the request.

the wearable app needs to determine that a connected node is capable of launching the activity. wearable app에서 작업을 수행할수 있는지 확인 하는 과정에서 작업을 수행할수 있는 기기의 app에서는 wearable app에게 본기기가 작업수행이 가능하다는 것을 알려야 하는 데 그방법은 아래와 같다.

  1. Create an XML configuration file in the res/values/ directory of your project and name it wear.xml.
  2. Add a resource named android_wear_capabilities to wear.xml.
  3. Define capabilities that the device provides.

Note: Capabilities are custom strings that you define and must be unique within your app.

<resources>
   <string-array name="android_wear_capabilities">
       <item>voice_transcription</item>
   </string-array>
</resources>

        Retrieve the nodes with the required capabilities (어느 app이 작업을 처리가능한지 확인하는 과정)

CapabilityApi.getCapability() method 를 이용한다.

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());
}

To detect capable nodes as they connect to the wearable device, register a CapabilityApi.CapabilityListener() instance to your GoogleApiClient.

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);
}

Note: If you create a service that extends WearableListenerService to detect capability changes, you may want to override the onConnectedNodes()method to listen to finer-grained connectivity details, such as when a wearable device switches from Wi-Fi to a Bluetooth connection to the handset. For more information on how to listen for important events, see Listen for Data Layer Events.

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 Node.isNearby() method.

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;
}

       Deliver the message

Once you’ve identified the best node to use, send the message using the MessageApi class.

Verify that the node is available before you attempt to send the message. This call is synchronous and blocks processing until the system queues the message for delivery.

Note: A successful result code does not guarantee delivery of the message. If your app requires data reliability, consider using DataItem objects or the ChannelApi class to send data between devices.

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() {
                     @Override
                     public void onResult(SendMessageResult sendMessageResult) {
                         if (!sendMessageResult.getStatus().isSuccess()) {
                             // Failed to send message
                         }
                     }
                 }
           );
   } else {
       // Unable to retrieve node with transcription capability
   }
}

Note: To learn more about asynchronous and synchronous calls to Google Play services and when to use each, see Communicate with Google Play Services.

You can also broadcast messages to all connected nodes.

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;
}

Receive a Message

To be notified of received messages, implement the MessageListener interface to provide a listener for message events. Then, register the listener with the MessageApi.addListener() method.

@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);
   }
}

Comments are closed.

Post Navigation