Skip to content

Instantly share code, notes, and snippets.

@jrejaud
Last active August 29, 2015 14:21
Show Gist options
  • Save jrejaud/9575f5b122c48e8157bb to your computer and use it in GitHub Desktop.
Save jrejaud/9575f5b122c48e8157bb to your computer and use it in GitHub Desktop.
Simplify Android Wear to Android Phone Messaging Boilderplate
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);
}
}
//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");
}
//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");
//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();
}
@jrejaud
Copy link
Author

jrejaud commented May 20, 2015

I simplified the rather long boiler plate for Android Mobile to Android Wear message sending.

Inspired by Socket.IO

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment