Search code examples
androidwear-osandroid-wear-data-apiandroid-googleapiclient

Null Data Item From Wearable.DataApi.getDataItem


My wearable has an Activity that implements DataApi.DataListener, this Activity sends a message in onConnected() to the handheld to update the requested data. When the handheld receives this message, it gets the data from a server, and passes it to a DataMap. This DataMap is sent with the following code:

NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();

for(Node node : nodes.getNodes()) {
    PutDataMapRequest dataRequest = PutDataMapRequest.create(mPath);
    dataRequest.getDataMap().putDataMapArrayList("/path", mData);

    PutDataRequest request = dataMapRequest.asPutDataRequest();
    DataApi.DataItemResult result = Wearable.DataApi.putDataItem(mGoogleApiClient, request).await();

    if(result.getStatus().isSuccess()) {
        Log.d(TAG, "DataMap: " + mData + " sent to: " + node.getDisplayName());
    }
}

It seems this code works correctly, as it outputs to logcat: "DataMap: <mData> sent to: 7f7fbd33". Then the handheld wearable receives this data in an AsyncTask using the following code:

NodeApi.GetLocalNodeResult localNode =
    Wearable.NodeApi.getLocalNode(getGoogleApiClient()).await();
Uri dataUri = new Uri.Builder().scheme(PutDataRequest.WEAR_URI_SCHEME)
    .authority(localNode.getNode().getId()).path("/path").build();
Log.d(dataUri.toString());

DataApi.DataItemResult itemResult =
    Wearable.DataApi.getDataItem(mGoogleApiClient, dataUri).await();
Log.d(TAG, itemResult.getStatus() + " dataItem=" + dataItem.getDataItem();

if(itemResult.getStatus().isSuccess() && itemResult.getDataItem() != null) {
    ...
}

The path seems to be correct: wear://7f7fbd33/path, but the result ends up being: Status{statusCode=SUCCESS, resolution=null} dataItem=null. Why is it giving me a null item?


Solution

  • On the watch device, why are you getting the localNode and constructing a dataUri using that? When a DataItem is created, its Uri includes the nodeId of the creator, so if you add a data item on the mobile device, its uri includes the nodeId of the mobile device so when you want to search for those items on a different node, you should use the nodeId of the creator (mobile device in your case) and shouldn't use the local nodeId of the receiver to construct your uri, see the JavaDoc. In many cases, you don't know the id of the creator, so you would use getDataItems() with partial uri, built from the path only. In addition, it is best to use onDataChanged() callback and then filter the messages based on their path.