2

On a phone device I have a WearableListenerService listening for input from a Android Wear device.

I am using both DataItems and Messages. DataItems sync between the two devices just fine, however, I am having problems with receiving messages on the phone.

I have tried the following:

  • Confirmed Wear has sent the message
  • Checked if package names are the same
  • Checked if signatures are the same (both are Android Debug)

Still, onMessageReceived is not called in DataLayerListenerService. Originally, I was using an activity and extending MessageListener which did not work either besides one point where it briefly worked.

Android Wear code

public static void sendMessageToDevice(final String commandPath, final byte[] additionalData)
{
    // Separate thread from UI thread
    new Thread(new Runnable()
    {
        @Override
        public void run()
        {
            String nodeId = null;

            // Find first connected device id

            NodeApi.GetConnectedNodesResult result =
                    Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();
            List<Node> nodes = result.getNodes();

            if (nodes.size() > 0)
            {
                nodeId = nodes.get(0).getId();
            }
            if (nodeId != null)
            {
                Wearable.MessageApi.sendMessage(mGoogleApiClient, nodeId,
                        commandPath, additionalData).setResultCallback(new ResultCallback<MessageApi.SendMessageResult>()
                {
                    @Override
                    public void onResult(MessageApi.SendMessageResult sendMessageResult)
                    {
                        if (!sendMessageResult.getStatus().isSuccess())
                        {
                            System.err.println("Message " + commandPath + " could not be sent.");
                        }
                    }
                });

                System.out.println("Command path is: " + commandPath);
            }
        }
    }).start();
}

Android device code

public class DataLayerListenerService extends WearableListenerService
{

@Override
public void onMessageReceived(MessageEvent messageEvent)
{
    System.out.println("Received command");
    String command = messageEvent.getPath();
    System.out.println("Received command is: " + command);
    if (command.contains("/mobile/input/"))
    {
        System.out.println(command);
    }
}

@Override
public void onDataChanged(DataEventBuffer dataEvents)
{
    for (DataEvent event : dataEvents)
    {
        if (event.getType() == DataEvent.TYPE_CHANGED)
        {
            DataItem item = event.getDataItem();
            DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap();
            String itemPath = item.getUri().getPath();
            if (itemPath.equals("/mobile/input/level"))
            {
                int level = dataMap.getInt("level");
                MainActivity.readLevel(level);
            }
        }
    }
}
}
emnes
  • 48
  • 6

1 Answers1

0

One possible issue could be the following: you are grabbing all connected nodes and then you grab the very first one to target for your message. That can very well end up being the cloud node (or another wearable device if you have multiple ones) and not your phone. The correct approach is to use the CapabilityApis to find the right node to send your message to. In your code, look at the node.toString() for the node that you selected to confirm that it is picking the cloud, to be sure that is the issue.

Ali Naddaf
  • 16,951
  • 2
  • 21
  • 28
  • Ah, I wrongfully assumed that the phone is the only thing that would be a connected node (in fact, it was suggested in a tutorial). Hope this can help others with this issue. Could you explain exactly what the cloud node is? Is it the GoogleApi? For reference: I printed out `nodeId.toString()` and indeed it was the cloud. Printed out all of the nodes and my phone came up second. I have implemented the CapabilityApi following [Android's tutorial](https://developer.android.com/training/wearables/data-layer/messages.html) and it works! Thanks!! – emnes Aug 11 '15 at 09:27
  • Could you please point me to the tutorial that gave the incorrect suggestion? If it is our official tutorials, I can get them corrected, thanks. – Ali Naddaf Aug 11 '15 at 15:27
  • [Toastdroid tutorial](http://toastdroid.com/2014/08/18/messageapi-simple-conversations-with-android-wear/). It's not an official Android one. – emnes Aug 12 '15 at 07:45
  • Also, I have another question in regards to WearableListenerService you said [here](http://stackoverflow.com/questions/31840366/is-wearablelistenerservice-better-than-service-with-data-and-message-listeners) that the WearableListenerService is not a long-living service but in this [Android tutorial](https://developer.android.com/training/wearables/data-layer/events.html) under With a Listener Activity it seems to implies otherwise? – emnes Aug 12 '15 at 07:53
  • Where in that document it talks about the WearableListenerService to be a long running service? – Ali Naddaf Aug 12 '15 at 14:42
  • Well the document talks about the WearableListenerService and then mentions an alternative (using Listeners) and says "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..." this implies the previous method (WearableListenerService) is long-running service? – emnes Aug 13 '15 at 08:27
  • No it doesn't and in fact, as I mentioned earlier, the WearbleListenerService (or any other service that is started via binding rather than startService() will be short lived; you can try that easily; implement onDestroy() and onCreated() to your WearableListernService and put a log statement there and then send a message; you will see onCreate() is called and then shortly after the message is handled, onDestroy() will be called. – Ali Naddaf Aug 13 '15 at 14:16
  • Just tried it and yes I see what you mean now. That's great! It would be nice if the document stated it explicitly, I find it to be confusing and unclear about this. – emnes Aug 14 '15 at 08:06
  • Documentation states that the service gets started when framework binds the request to your implementation of the service and when a service is started that way, as a general rule, it runs till it is done (stated clearly in the development section on Services). I'll see if I can add a comment there to make it clear for WearableServiceListener as well. – Ali Naddaf Aug 14 '15 at 19:35