Reputation: 165
I m trying to use the new android wear comms API, specifically the Message API to which end I have an Activity plus a service in my watch application and an Activity as the test app in the phone.
I have comms working fine in both directions and I can start up my Watch Activity via the comms by sending messages from the Phone app which also works fine except for a single issue which only occurs immediately after a reboot of the watch hardware:
If I start my Watch app via a comms message call immediately after a reboot without first running a Watch App Activity then the message reply returned from the Watch is lost and not seen by the Phone App.
If I run an Activity in the Watch App after the reboot and before initiating comms from the Phone App then the comms messages work fine, even if I close the Watch Activity before sending any messages.
My WearableListenerService code on the Watch side looks like the following (much abbreviated)
public class MyClass extends WearableListenerService
implements MessageApi.MessageListener,
ConnectionCallbacks,
OnConnectionFailedListener
{
...
@Override
public void onCreate()
{
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.build();
}
@Override
public void onDestroy()
{
mGoogleApiClient.disconnect();
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
int result = super.onStartCommand(intent, flags, startId);
mGoogleApiClient.connect();
return result;
}
@Override
public void onMessageReceived(MessageEvent messageEvent)
{
comms.handleReceivedMessage (messageEvent);
}
public final void txReply(String txMessage, String nodeId)
{
Wearable.MessageApi.sendMessage(mGoogleApiClient,
nodeId,
MESSAGE_RECEIVED_PATH,
txMessage.getBytes());
}
@Override
public void onConnected(Bundle bundle)
{
Wearable.MessageApi.addListener(mGoogleApiClient, this);
}
@Override
public void onConnectionSuspended(int arg0)
{
// TODO Auto-generated method stub
}
@Override
public void onConnectionFailed(ConnectionResult arg0)
{
// TODO Auto-generated method stub
}
}
My comms.handleReceivedMessage() function directly calls the txReply() function above and I have verified the data is correct using LogCat.
I'd be extremely grateful for any pointers as to what I may be missing which prevents my first Watch App message from being received by the Phone App. Again, this behavious only occurs immediately after a reboot iff the Watch App Activity has not been run before a message is received.
--EDIT-- @ Murphy:
Well, I looked at your code and it seems almost the same as what I already have, in fact I have the following in place of your call :
NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();
for (Node node : nodes.getNodes())
{
// Send message and wait for result
SendMessageResult result = Wearable.MessageApi.sendMessage(mGoogleApiClient,
node.getId(),
MESSAGE_RECEIVED_PATH,
txm.getBytes()).await();
}
So the differences are not significant in respect of comms from the Watch getting lost, but thanks anyway for your help.
Regards,
Upvotes: 2
Views: 2007
Reputation: 6522
First of all, you don't need to addListener for message API and implement MessageApi.MessageListener since WearableListenerService does it for you, you can just override method onMessageReceived.
As for the problem, you should ensure google api is connected (as I mention above, WearableListenerService is managed by the system, so you can receive a message earlier than your api client is connected):
public final void txReply(String txMessage, String nodeId)
{
if (!mGoogleApiClient.isConnected())
{
ConnectionResult connectionResult
= mGoogleApiClient.blockingConnect(30, TimeUnit.SECONDS);
if (!connectionResult.isSuccess()) {
//log or show error
return;
}
}
Wearable.MessageApi.sendMessage(mGoogleApiClient,
nodeId,
MESSAGE_RECEIVED_PATH,
txMessage.getBytes());
}
Upvotes: 1
Reputation: 4876
Having the googleApiClient
connected does not ensure you have a connection with your Wear
.
I recommend you to check on the phone side the Wear
connection before sending the Message
:
Wearable.NodeApi.getConnectedNodes(getGoogleApiClient()).setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() {
@Override
public void onResult(NodeApi.GetConnectedNodesResult getConnectedNodesResult) {
boolean isPeerConnected = getConnectedNodesResult.getNodes().size() > 0;
}});
Edit: If it's not connected, then I you can send when it's connecting using:
Wearable.NodeApi.addListener(getGoogleApiClient(), new NodeApi.NodeListener() {
@Override
public void onPeerConnected(Node node) {
// TODO send message
}
@Override
public void onPeerDisconnected(Node node) {
}
})
Upvotes: 0