Search code examples
wear-osandroid-wear-data-api

Wearable DataAPI syncing issue with multiple watches (Looping)


I have a watchface with a companion app for phone. It uses Wearable.DataApi to sync changes between the phone and watch. I have a DataApi.DataListener setup and sync changes made on the watch or phone side. I have no issue with a phone and ONE watch communicating.

The issue is when i have multiple watches using the same watch face if changes on watch or phone side are made quickly it seems to go into a loop and start flashing the changes on all devices. So if im changing the color by tapping watch if I press a few times quickly to do that all devices start cycling through all colors and takes some time before it catches up and stops.

If I change options slowly there is no problem. I put a log in the DataApi listener and I see both uri's making the change but just seems to loop for some reason when changed quickly. Is there anyway to prevent this?

I know this might not seem like a big issue but if a user has 2 watches and accidently changes an option or options quickly it will start with the options and or colors changing. I want to prevent that from happening.

This is how im adding my listener in the onConnected method

 Wearable.DataApi.addListener(mGoogleApiClient, dataListener);

And this is my listener method

DataApi.DataListener dataListener = new DataApi.DataListener() {
        @Override
        public void onDataChanged(DataEventBuffer dataEvents) {
            Log.d(TAG, "onDataChanged");

            for (DataEvent event : dataEvents) {
                Log.d(TAG, "dataEvent.uri: " + event.getDataItem().getUri().toString());

                DataMap item = DataMapItem.fromDataItem(event.getDataItem()).getDataMap();

               /////other code to set data/////

            }
            updateCanvas();
        }
    };

Solution

  • You should be able to avoid this by filtering out dataEvents that originated from the local node (i.e., the device that the code is running on).

    Get the local node ID with code like this:

    NodeApi.GetLocalNodeResult nodeResult = Wearable.NodeApi.getLocalNode(googleApiClient).await();
    String localNodeID = getLocalNodeResult.getNode().getId();
    

    Then, put code like this inside your for loop to do the filtering:

    Uri uri = item.getUri();
    String nodeID = uri.getHost();
    if (nodeID.equals(localNodeID)) {
        // Skip changes originating on this device
        continue;
    }