I am attempting to read a feed from a URL in the form of a JSON Object, and pass that feed to a Wearable device to display as a list using the Data API. This JSON Object contains an array of objects, each object containing a few elements. Something like this:
{ "items":[
{ "title":"item 1", "element_1":"element 1", "element_2":"element 2" }
{ "title":"item 2", "element_1":"element 1", "element_2":"element 2" }
{ "title":"item 3", "element_1":"element 1", "element_2":"element 2" }
]}
I can get these items into an ArrayList
of objects using GSON, or Jackson (though I think I prefer GSON), but I do not know how I would be able to that ArrayList
of objects to the wearable. From what I can tell, I cannot. I would like to know if there is a way to do this, or if not, some sort of best practices on how I should go about this? Should I just get the JSON as a string, pass the string to the wearable, and parse it afterwards? I do not know if this would be inefficient if the string were very large though, considering I do not know how large the list of JSON objects could get. Also I know it is possible to parse a string with GSON, but I do not know if this is inefficient as well.
I found the Android Wear Sample XYZTouristAttractions, and this is my current code based on that example. Firstly, I created a shared library to reduce duplicate code. This shared library contains the Item
class that holds the JSON data. I use this class in my DownloadArrayListTask
on the handheld, which takes the JSON Object from the input stream and puts the data in an ArrayList
of Item
objects.
@Override
protected ArrayList<Item> doInBackground(URL... params) {
URL url = params[0];
ArrayList<Item> items = new ArrayList<>();
try {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
try {
InputStreamReader input = new InputStreamReader(connection.getInputStream());
Type listType = new TypeToken<Map<String, ArrayList<Item>>>(){}.getType();
Gson gson = new GsonBuilder().create();
Map<String, ArrayList<Item>> treeMap = gson.fromJson(input, listType);
items = treeeMap.get("items");
input.close();
} finally {
connection.disconnect();
}
} catch (IOException exception) {
exception.printStackTrace();
}
return items
}
This ArrayList
is broken apart into strings in the DataLayerListenerService
and placed in an ArrayList
of DataMap
objects for the wearable to receive.
@Override
public void onMessageReceived(MessageEvent messageEvent) {
GoogleApiClient googleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API).build();
ConnectionResult connectionResult = googleApiClient.blockingConnect(30, TimeUnit.SECONDS);
if(!connectionResult.isSuccess()) {
Log.e(TAG, "Failed to connect to Google API Client");
return;
}
if(messageEvent.getPath().equals("/update_path") {
ArrayList<Item> items = new ArrayList<>()
try {
items = new DownloadArrayListTask().execute(new URL("http://my_url")).get();
} catch (MalformedURLException | InterruptedException | ExecutionException exception) {
exception.printStackTrace();
}
ArrayList<DataMap> itemMaps = new ArrayList<>(items.size());
for(Item item : items) {
DataMap dataMap = new DataMap();
dataMap.putString("title", item.getTitle());
dataMap.putString("element1", item.getElement1());
dataMap.putString("element2", item.getElement2());
itemMaps.add(dataMap);
}
new Thread(new Runnable() {
@Override
public void run() {
NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleApiClient).await();
for(Node node : nodes.getNodes()) {
PutDataMapRequest dataMapRequest = PutDataMapRequest.create("/item_path");
dataMapRequest.getDataMap().putDataMapArrayList("item_key", itemMaps);
PutDataRequest request = dataMapRequest.asPutDataRequest();
DataApi.DataItemResult result = Wearable.DataApi.putDataItem(googleApiClient, request).await();
if(!result.getStatus().isSuccess()) {
Log.d(TAG, "Failed to send data");
}
}
}
}).start();
}
}
Then the wearable device receives this ArrayList
of DataMap
objects, and uses its own AsyncTask
to put them back into an ArrayList
of Item
objects.
@Override
protected ArrayList<Item> doInBackground(Uri... params) {
Uri uri = params[0];
ArrayList<Item> items = new ArrayList<>();
GoogleApiClient googleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API).build();
ConnectionResult connectionResult = googleApiClient.blockingConnect(30, TimeUnit.SECONDS);
if(!connectionResult.isSuccess()) {
Log.e(TAG, "Failed to connect to Google API Client");
return;
}
DataItemBuffer results = Wearable.DataApi.getDataItems(googleApiClient).await();
if(results.getStatus().isSuccess() && results.getCount() != 0) {
DataMapItem dataMapItem = DataMapItem.fromDataItem(results.get(0);
List<DataMap> data = dataMapItem.getDataMap().getDataMapArrayList("item_key");
for(DataMap dataItem : data) {
Item item = new Item(dataItem.getString("title"),
dataItem.getString("element1"),
dataItem.getString("element2"));
items.add(item);
}
} else {
Log.d(TAG, "Failed to obtain data");
} return items;
}