Last active
August 29, 2015 14:21
-
-
Save jrejaud/9575f5b122c48e8157bb to your computer and use it in GitHub Desktop.
Simplify Android Wear to Android Phone Messaging Boilderplate
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.crejaud.jrejaud.androidwearmessenger; | |
import android.app.Activity; | |
import android.content.Context; | |
import android.os.AsyncTask; | |
import android.os.Bundle; | |
import android.util.Log; | |
import android.widget.Toast; | |
import com.google.android.gms.common.ConnectionResult; | |
import com.google.android.gms.common.api.GoogleApiClient; | |
import com.google.android.gms.wearable.MessageApi; | |
import com.google.android.gms.wearable.MessageEvent; | |
import com.google.android.gms.wearable.NodeApi; | |
import com.google.android.gms.wearable.Wearable; | |
import java.io.UnsupportedEncodingException; | |
import java.util.concurrent.Semaphore; | |
/** | |
* Created by jrejaud on 5/18/2015. | |
*/ | |
public class AndroidWearMessenger implements MessageApi.MessageListener{ | |
private static AndroidWearMessenger ourInstance = new AndroidWearMessenger(); | |
private GoogleApiClient googleApiClient = null; | |
private final Semaphore nodeFound = new Semaphore(0,true); | |
private String TAG = "AndroidWearMessenger"; | |
private Context context; | |
private String phoneNode = null; | |
public static AndroidWearMessenger getInstance() { | |
return ourInstance; | |
} | |
private AndroidWearMessenger() { | |
} | |
private void showErrorAndCloseApp(String message, boolean closeApp) { | |
Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); | |
disconnect(); | |
if (closeApp) { | |
((Activity)context).finish(); | |
} | |
} | |
public void setupAndConnect(Context context) { | |
this.context = context; | |
Log.d(TAG,"Starting up Google Api Client"); | |
googleApiClient = new GoogleApiClient.Builder(context) | |
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() { | |
@Override | |
public void onConnected(Bundle bundle) { | |
Log.d(TAG, "Google Api Client Connected, bundle: " + bundle); | |
//Start looking for a node | |
new Thread(new Runnable() { | |
@Override | |
public void run() { | |
Log.d(TAG, "Start Node Search"); | |
NodeApi.GetConnectedNodesResult nodes = | |
Wearable.NodeApi | |
.getConnectedNodes(googleApiClient).await(); | |
if (nodes == null) { | |
Log.d(TAG, "No nodes found"); | |
showErrorAndCloseApp("Error, cannot find node, make sure watch is paired to phone",true); | |
} | |
phoneNode = nodes.getNodes().get(0).getId(); | |
Log.d(TAG,"Node found: "+phoneNode); | |
nodeFound.release(); | |
} | |
}).start(); | |
} | |
@Override | |
public void onConnectionSuspended(int i) { | |
Log.d(TAG, "onConnectedSuspended: " + i); | |
} | |
}) | |
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() { | |
@Override | |
public void onConnectionFailed(ConnectionResult result) { | |
showErrorAndCloseApp("Error, cannot connect", true); | |
} | |
}) | |
.addApi(Wearable.API) | |
.build(); | |
googleApiClient.connect(); | |
} | |
public GoogleApiClient getGoogleApiClient() { | |
return googleApiClient; | |
} | |
public void disconnect() { | |
if (googleApiClient!=null) { | |
googleApiClient.disconnect(); | |
} | |
Wearable.MessageApi.removeListener(AndroidWearMessenger.getInstance().getGoogleApiClient(), this); | |
} | |
public void sendMessage(String path, String message) { | |
new sendMessageTask(path,message).execute(); | |
} | |
private class sendMessageTask extends AsyncTask<Void, Void, Boolean> { | |
private String path; | |
private String message; | |
public sendMessageTask(String path, String message) { | |
this.path = path; | |
this.message = message; | |
} | |
@Override | |
protected Boolean doInBackground(Void... voids) { | |
while (phoneNode==null) { | |
Log.d(TAG,"Node not found yet, waiting until one is found to send message"); | |
try { | |
nodeFound.acquire(); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
Log.d(TAG,"Sending message to node: "+phoneNode); | |
MessageApi.SendMessageResult result = Wearable.MessageApi.sendMessage( | |
googleApiClient, phoneNode, path, message.getBytes()).await(); | |
if (!result.getStatus().isSuccess()) { | |
return false; | |
} | |
return true; | |
} | |
@Override | |
protected void onPostExecute(Boolean messageResponse) { | |
if (messageResponse) { | |
Log.d(TAG,"Message "+path+" : "+message+" sent successfully"); | |
} else { | |
showErrorAndCloseApp("Could not send message "+path+" : "+message,false); | |
} | |
super.onPostExecute(messageResponse); | |
} | |
} | |
//Code for receiving messages | |
private String receiverPath= null; | |
private AndroidWearMessageReceivedInterface androidWearMessageReceivedInterface; | |
@Override | |
public void onMessageReceived(final MessageEvent messageEvent) { | |
if (receiverPath==null) { | |
Log.d(TAG, "You haven't set a path yet! Cannot receive messages until you do"); | |
return; | |
} | |
if (messageEvent.getPath().equals(receiverPath)) { | |
((Activity)context).runOnUiThread(new Runnable() { | |
@Override | |
public void run() { | |
String data = null; | |
try { | |
data = new String(messageEvent.getData(),"UTF-8"); | |
androidWearMessageReceivedInterface.messageReceived(messageEvent.getPath(), data); | |
} catch (UnsupportedEncodingException e) { | |
e.printStackTrace(); | |
} | |
} | |
}); | |
} | |
} | |
public interface AndroidWearMessageReceivedInterface { | |
void messageReceived(String path, String message); | |
} | |
public void startMessageListener(String path) { | |
androidWearMessageReceivedInterface = (AndroidWearMessageReceivedInterface) context; | |
this.receiverPath = path; | |
Wearable.MessageApi.addListener(AndroidWearMessenger.getInstance().getGoogleApiClient(), this); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Need to implement AndroidWearMessenger.AndroidWearMessageReceivedInterface in activity and override messageReceived to receive a message | |
//Don't forget to startMessageListener with the path that you want to listen too | |
public class MainActivity extends ActionBarActivity implements AndroidWearMessenger.AndroidWearMessageReceivedInterface { | |
@Override | |
public void messageReceived(String path, String message) { | |
Toast.makeText(this, "Get message: " + path, Toast.LENGTH_SHORT).show(); | |
} | |
AndroidWearMessenger androidWearMessenger = AndroidWearMessenger.getInstance(); | |
androidWearMessenger.setupAndConnect(this); | |
androidWearMessenger.startMessageListener("myPath"); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Use setupAndConnect to setup Google API Client | |
//Use sendMessage to send a message to the node | |
AndroidWearMessenger androidWearMessenger = AndroidWearMessenger.getInstance(); | |
androidWearMessenger.setupAndConnect(this); | |
androidWearMessenger.sendMessage("myPath", "myMessage"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Remember to disconnect (both the Google Api Client and the Listener) once you no longer need it | |
@Override | |
protected void onDestroy() { | |
super.onDestroy(); | |
AndroidWearMessenger androidWearMessenger = AndroidWearMessenger.getInstance(); | |
androidWearMessenger.disconnect(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I simplified the rather long boiler plate for Android Mobile to Android Wear message sending.
Inspired by Socket.IO