package com.crossbow.wear.receiver; import android.content.Context; import android.os.Bundle; import android.util.Log; import com.android.volley.NetworkResponse; import com.android.volley.RequestQueue; import com.android.volley.VolleyError; import com.crossbow.wear.core.RequestSerialUtil; import com.crossbow.wear.core.ResponseTransformer; import com.crossbow.wear.core.WearDataRequest; import com.crossbow.wear.core.WearNetworkResponse; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.api.PendingResult; import com.google.android.gms.common.api.ResultCallback; import com.google.android.gms.wearable.MessageApi; import com.google.android.gms.wearable.MessageEvent; import com.google.android.gms.wearable.Wearable; import java.io.IOException; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.Queue; /** * Handles the creation and registering of the google play services client as well as * sending the request from the wearable and send the response from the wearable */ public class WearRequestHandler { private final Map<String, ResponseTransformer> transformerMap = new HashMap<>(); private RequestQueue requestQueue; private GoogleApiClient googleApiClient; private Queue<MessageEvent> messages = new LinkedList<>(); boolean googlePlayServicesConnected = false; public WearRequestHandler(Context context, RequestQueue requestQueue, Map<String, ResponseTransformer> transformerMap) { this.requestQueue = requestQueue; this.transformerMap.putAll(transformerMap); googleApiClient = new GoogleApiClient.Builder(context.getApplicationContext()) .addApi(Wearable.API) .addConnectionCallbacks(connectionCallbacks) .addOnConnectionFailedListener(connectionFailedListener) .build(); googleApiClient.connect(); } public static boolean isWearMessage(MessageEvent messageEvent) { return messageEvent.getPath().contains("crossbow_wear"); } public void sendRequest(MessageEvent messageEvent) { if(googlePlayServicesConnected) { setWearRequest(messageEvent); } else { messages.add(messageEvent); } } public void disconnect() { if(googleApiClient.isConnected()) { googleApiClient.disconnect(); } } private void setWearRequest(MessageEvent messageEvent) { byte[] data = messageEvent.getData(); final String sourceNodeID = messageEvent.getSourceNodeId(); try { WearDataRequest wearDataRequest = RequestSerialUtil.deSerializeRequest(data); wearDataRequest.setTransformerMap(transformerMap); wearDataRequest.setListener(new WearDataRequest.Listener() { @Override public void onResponse(String uuid, NetworkResponse response) { sendResultToWear(sourceNodeID, true, uuid, response); } }); wearDataRequest.setErrorListener(new WearDataRequest.ErrorListener() { @Override public void onErrorResponse(String uuid, VolleyError error) { sendResultToWear(sourceNodeID, true, uuid, null); } }); requestQueue.add(wearDataRequest); } catch (IOException e) { e.printStackTrace(); } } private void sendPendingRequests() { while (!messages.isEmpty()) { setWearRequest(messages.poll()); } } private void sendResultToWear(String sourceNodeID, boolean success, String uuid, NetworkResponse networkResponse) { WearNetworkResponse wearNetworkResponse = new WearNetworkResponse(success, uuid, networkResponse); byte[] data = wearNetworkResponse.toByteArray(); PendingResult<MessageApi.SendMessageResult> result = Wearable.MessageApi.sendMessage(googleApiClient, sourceNodeID, "/crossbow_wear/" + uuid, data); result.setResultCallback(new ResultCallback<MessageApi.SendMessageResult>() { @Override public void onResult(MessageApi.SendMessageResult sendMessageResult) { Log.i("TAG", "Request sent back result = " + sendMessageResult.getStatus().isSuccess()); } }); } private final GoogleApiClient.ConnectionCallbacks connectionCallbacks = new GoogleApiClient.ConnectionCallbacks() { @Override public void onConnected(Bundle bundle) { googlePlayServicesConnected = true; sendPendingRequests(); } @Override public void onConnectionSuspended(int i) { googlePlayServicesConnected = false; } }; private final GoogleApiClient.OnConnectionFailedListener connectionFailedListener = new GoogleApiClient.OnConnectionFailedListener() { @Override public void onConnectionFailed(ConnectionResult connectionResult) { googlePlayServicesConnected = false; } }; }