Java – send a message from wearable to mobile phone and reply immediately
I've been fighting the Android wear message API, and I can finally accept that I need some help
My application is very simple The mobile part consists of a mainactivity (except for the service that displays "Hello world" and an extensible wearablelistener service, it only makes a mainactivity, while the wear part is only a mainactivity and implements messageapi. Messagelistener
The idea is simple: press the button on the wear device, which sends a message to mobile When the mobile station receives the message, it will display toast with the sender's message path (e.g. / mobile) After doing so, mobile should send the message back to the wear device using my reply () method All I want to do is record this message
I can achieve the first part of the perfect fine After pressing the button, the phone will pop up a toast saying "/ mobile" However, the answer seems to be lost in one; No errors, but no messages
Can someone help me understand what I'm doing wrong? I have pasted my file below
This is the tutorial I'm following Cheers!
Key words: mainactivity java
package org.thecosmicfrog.toastdroidmessageapitutorial; import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.support.wearable.view.WatchViewStub; import android.util.Log; import android.view.View; 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.Node; import com.google.android.gms.wearable.NodeApi; import com.google.android.gms.wearable.Wearable; import java.util.List; import java.util.concurrent.TimeUnit; public class MainActivity extends Activity implements MessageApi.MessageListener { private final String LOG_TAG = MainActivity.class.getSimpleName(); private static final long CONNECTION_TIME_OUT_MS = 100; private static final String MOBILE_PATH = "/mobile"; private GoogleApiClient googleApiClient; private String nodeId; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initGoogleApiClient(); final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub); stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() { @Override public void onLayoutInflated(WatchViewStub stub) { initWidgets(); } }); } private void initGoogleApiClient() { googleApiClient = getGoogleApiClient(this); retrieveDeviceNode(); } private GoogleApiClient getGoogleApiClient(Context context) { return new GoogleApiClient.Builder(context) .addApi(Wearable.API) .build(); } private void retrieveDeviceNode() { new Thread(new Runnable() { @Override public void run() { if (googleApiClient != null && !(googleApiClient.isConnected() || googleApiClient.isConnecting())) googleApiClient.blockingConnect(CONNECTION_TIME_OUT_MS,TimeUnit.MILLISECONDS); NodeApi.GetConnectedNodesResult result = Wearable.NodeApi.getConnectedNodes(googleApiClient).await(); List<Node> nodes = result.getNodes(); if (nodes.size() > 0) nodeId = nodes.get(0).getId(); Log.v(LOG_TAG,"Node ID of phone: " + nodeId); googleApiClient.disconnect(); } }).start(); } private void initWidgets() { findViewById(R.id.button_toast).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { sendToast(); } }); } private void sendToast() { if (nodeId != null) { new Thread(new Runnable() { @Override public void run() { if (googleApiClient != null && !(googleApiClient.isConnected() || googleApiClient.isConnecting())) googleApiClient.blockingConnect(CONNECTION_TIME_OUT_MS,TimeUnit.MILLISECONDS); Wearable.MessageApi.sendMessage(googleApiClient,nodeId,MOBILE_PATH,null).await(); googleApiClient.disconnect(); } }).start(); } } @Override public void onMessageReceived(MessageEvent messageEvent) { Log.v(LOG_TAG,"In onMessageReceived()"); if (messageEvent.getPath().equals("/wear")) { Log.v(LOG_TAG,"Success!"); } } }
Mobile phone: listener service java
package org.thecosmicfrog.toastdroidmessageapitutorial; import android.util.Log; import android.widget.Toast; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.wearable.MessageEvent; import com.google.android.gms.wearable.Wearable; import com.google.android.gms.wearable.WearableListenerService; import java.util.concurrent.TimeUnit; public class ListenerService extends WearableListenerService { private final String LOG_TAG = ListenerService.class.getSimpleName(); private static GoogleApiClient googleApiClient; private static final long CONNECTION_TIME_OUT_MS = 100; private static final String WEAR_PATH = "/wear"; private String nodeId; @Override public void onMessageReceived(MessageEvent messageEvent) { if (messageEvent.getPath().equals("/mobile")) { nodeId = messageEvent.getSourceNodeId(); Log.v(LOG_TAG,"Node ID of watch: " + nodeId); showToast(messageEvent.getPath()); reply(WEAR_PATH); } } private void showToast(String message) { Toast.makeText(this,message,Toast.LENGTH_LONG).show(); } private void reply(final String path) { googleApiClient = new GoogleApiClient.Builder(getApplicationContext()) .addApi(Wearable.API) .build(); Log.v(LOG_TAG,"In reply()"); Log.v(LOG_TAG,"Path: " + path); if (googleApiClient != null && !(googleApiClient.isConnected() || googleApiClient.isConnecting())) googleApiClient.blockingConnect(CONNECTION_TIME_OUT_MS,TimeUnit.MILLISECONDS); Wearable.MessageApi.sendMessage(googleApiClient,path,null).await(); googleApiClient.disconnect(); } }
Mobile mainactivity is very simple, so I've left it for clarity
Solution
You never call MessageApi. in your Wear activity. Addlistener(), so your messagelistener has never registered to receive messages When your activity is destroyed, you should also call messageapi removeListener().
Note: both methods require a connected Google API client If you keep the Google API client throughout the event instead of trying to connect / removelistener() / disconnect in ondestroy(), you may make the logic easier