16

I'm testing the Wearable Data Layer Api as described in the Android tutorial.

There is a low level API based around DataItem, which can have only a byte array as payload, so the training recommends using PutDataMapRequest, which seems to be basically equivalent to a Bundle (i.e. a serializable map) when using Intents. You basically create an instance of this class, then fill the values, and send it.

private final static String DATA_PATH = "/testdata";

PutDataMapRequest dataMap = PutDataMapRequest.create(DATA_PATH);
dataMap.getDataMap().putInt(...);

PutDataRequest request = dataMap.asPutDataRequest();
PendingResult<DataApi.DataItemResult> pendingResult = Wearable.DataApi.putDataItem(mGoogleApiClient, request);
pendingResult.setResultCallback(...);

Now, I want to check if this data was stored correctly (for testing, on the handheld itself, I'm not concerned about the wearable right now). The appropriate methods for this are in the DataApi class, so I can call:

PendingResult<DataApi.DataItemResult> pending;
pending = Wearable.DataApi.getDataItem(mGoogleApiClient, uri);
pending.setResultCallback(...);

and then use DataMapItem.fromDataItem() inside the callback to get the value.

The problem is: what is the actual Uri to request the DataItemResult?

The data is stored, because if I use Wearable.DataApi.getDataItems(mGoogleApiClient) to iterate over all stored data, it's indeed there, and the Uri is:

"wear://<some guid here>/testdata"

And using this Uri with DataApi.getDataItem() returns the correct result. But I'm clueless as to how to generate it, since I only used the /testdata part to create the PutDataRequest...

Or am I doing things incorrectly?

matiash
  • 54,791
  • 16
  • 125
  • 154

1 Answers1

25

The uri's authority (which is described as <some guid here> in your post) is Node Id which is available via Node API. In summary, you can construct the Uri as following.

private Uri getUriForDataItem() {
    // If you've put data on the local node
    String nodeId = getLocalNodeId();
    // Or if you've put data on the remote node
    // String nodeId = getRemoteNodeId();
    // Or If you already know the node id
    // String nodeId = "some_node_id";
    return new Uri.Builder().scheme(PutDataRequest.WEAR_URI_SCHEME).authority(nodeId).path("/path_to_data").build();
}

private String getLocalNodeId() {
    NodeApi.GetLocalNodeResult nodeResult = Wearable.NodeApi.getLocalNode(mGoogleApiClient).await();
    return nodeResult.getNode().getId();
}

private String getRemoteNodeId() {
    HashSet<String> results = new HashSet<String>();
    NodeApi.GetConnectedNodesResult nodesResult =
            Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();
    List<Node> nodes = nodesResult.getNodes();
    if (nodes.size() > 0) {
        return nodes.get(0).getId();
    }
    return null;
}
Poly
  • 1,053
  • 1
  • 11
  • 16
  • Perfect! I hadn't seen this. And I assume each connected device has its own node id? – matiash Jul 07 '14 at 17:40
  • Yes it is. node id and item url are mentioned a little bit in this video as well. https://www.google.com/events/io/schedule/session/9bf77f55-afbe-e311-b297-00155d5066d7 – Poly Jul 08 '14 at 06:19
  • Yes, I saw that video after I read your answer. Thanks again! – matiash Jul 08 '14 at 12:01
  • 5
    Actually the node can be omitted. If you use only the scheme and the path you will retrieve a `DataItemBuffer` containing all the `DataItem` elements at the given path. You can then iterate through them. – ZhDev Jul 10 '14 at 23:42
  • 1
    This doesnt work for me on the remote device... on the device the item is created it works but not on the other. BUT I am reciving onDataChanged events on the remote device. My Uris seem to be correct (the one I use to get the DataItem is the same as I get from the event in onDataChanged). Any suggestions? Additional info: Since I wasnt able to get Android Studio to work for a mobile project I'm developing the smartphone part using eclipse but for the wear part I use Android Studio. – Eric Oct 08 '15 at 21:35