1

I have spent a few days trying to share a dataItem between a wear device and a phone, but I have had no success. No matter what I do, the wearable only listens for its own dataItem. I mean, if I create a dataResquest inside the wear activity asking for a StringArray, the phone will receive it, I can change it on the phone service, but the wearable will still get the original StringArray when its onDataChanged is called.

I have even tried sending a message from the wearable to the phone, initiate a request from the phone, and have the wearable just listen for it, but it never receives anything if I do that.

This is what the WearListenerService currently looks like on the phone:

public class WearableService extends WearableListenerService {
    @Override
    public void onDataChanged(DataEventBuffer dataEvents) {
        super.onDataChanged(dataEvents);
        GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(Wearable.API)
                .build();
        mGoogleApiClient.connect();
        for (DataEvent event : dataEvents) {
            if (event.getType() == DataEvent.TYPE_CHANGED) {
                DataItem item = event.getDataItem();
                item.freeze();
                DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap();
                dataMap.putStringArray(Constants.SET_LIST, new String[]{"table 14", "table 27", "table 12323"});
                PutDataRequest putDataReq = PutDataRequest.createFromDataItem(item).setUrgent();
                Wearable.DataApi.putDataItem(mGoogleApiClient, putDataReq);
                return;
            }
        }
    }
}

And this is what part of my wearable's activity looks like:

public class MainActivity extends Activity implements
    DataApi.DataListener,
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener {

    private GoogleApiClient mGoogleApiClient;
    private String[] set_list = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.empty_database);

    // Listen for data item events
    // http://developer.android.com/training/wearables/data-layer/data-items.html
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addApi(Wearable.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build();

    mGoogleApiClient.connect();
}

    @Override
    public void onConnected(Bundle bundle) {
        Wearable.DataApi.addListener(mGoogleApiClient, this);

        // Send request to phone asking for set list
        PutDataMapRequest putDataMapReq = PutDataMapRequest.create(Constants.SET_LIST);
        putDataMapReq.getDataMap().putLong("time", new Date().getTime());
        putDataMapReq.getDataMap().putStringArray(Constants.SET_LIST, set_list);
        PutDataRequest putDataReq = putDataMapReq.asPutDataRequest().setUrgent();
        Wearable.DataApi.putDataItem(mGoogleApiClient, putDataReq);
    }
    @Override
    public void onDataChanged(DataEventBuffer dataEvents) {
        for (DataEvent event : dataEvents) {
            if (event.getType() == DataEvent.TYPE_CHANGED) {
                // DataItem changed
                DataItem item = event.getDataItem();
                DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap();
                set_list = dataMap.getStringArray("/new_string");
                if (set_list != null) {
                    createList();
                    return;
                }
            }
        }
    }

Does anyone know what could be causing this? Thank you.

Eric Abreu
  • 171
  • 1
  • 10
  • I managed to fix it by sending a message to the phone using the MessageAPI and sending data back to the watch using the DataAPI – Eric Abreu Jan 20 '16 at 06:09

1 Answers1

0

Solved the issue by sending a message to the phone asking for data using the MessageAPI and by having the phone use the DataAPI to send requested data to the wearable.

Wearable

I call sendMessage inside onConnected right after adding a listener from the DataAPI:

@Override
public void onConnected(Bundle bundle) {
    Wearable.DataApi.addListener(mGoogleApiClient, this);
    sendMessage(Constants.SET_LIST_PATH, Constants.BLANK_MESSAGE);
}

private void sendMessage(final String path, final String message) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();
            for (Node node : nodes.getNodes()) {
                Wearable.MessageApi.sendMessage(
                        mGoogleApiClient, node.getId(), path, message.getBytes()).await();
            }
        }
    }).start();
}

@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();
            set_list = dataMap.getStringArray(Constants.SET_LIST_PATH);
            if (set_list != null) {
                createList();
            }
        }
    }
}

Mobile

I used this answer to fix my wearable service. When the phone receives a message from the watch, it needs to create a new GoogleApiClient and use it to send the data via the DataAPI:

@Override
public void onMessageReceived(MessageEvent messageEvent) {
    super.onMessageReceived(messageEvent);

    // Do whatever you need to do with your message here

    sendData();
}

private void sendData() {
    GoogleApiClient mGoogleApiClient = wearConnect();
    final PutDataMapRequest putRequest = PutDataMapRequest.create(Constants.SET_LIST);
    final DataMap map = putRequest.getDataMap();

    // Add the time to the data map request if you want onDataChanged 
    // to be called every time you receive a message even if the data 
    // you are sending to the wearable is not new
    map.putLong("time", new Date().getTime());

    // Add your stuff here

    Wearable.DataApi.putDataItem(mGoogleApiClient, putRequest.asPutDataRequest());
}

private GoogleApiClient wearConnect() {
    GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
                @Override
                public void onConnected(Bundle connectionHint) {
                }

                @Override
                public void onConnectionSuspended(int cause) {
                }
            })
            .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
                @Override
                public void onConnectionFailed(ConnectionResult result) {
                }
            })
            .addApi(Wearable.API)
            .build();
    mGoogleApiClient.connect();
    return mGoogleApiClient;
}
Community
  • 1
  • 1
Eric Abreu
  • 171
  • 1
  • 10