Search code examples
androidwear-osgoogle-api-clientgdata-apiandroid-wear-data-api

WearableListenerService onMessageReceived() not called


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

Solution

  • 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.