WearableListenerService onMessageReceived sometimes not working

Viewed 21

WearableListenerService receiving messages between phone and watch works fine, but sometimes not...

with below source code,

  1. Wear device will send "/fish/check" every second
  2. Mobile device sends back "/fish/ready" when message received

it works, but sometimes not ... any suggestions?

by the way, every time the service does not function, set exported to false and run, then set it back to true and run, and things go normal again.

notes:

Wearable.getMessageClient(context).sendMessage(node, path, msg) both sent onSuccess on phone and watch

same application id on phone & watch

service exported="true" both on phone & watch

onMessageReceived listener on MainActivity always received correct event

what I tried:

  • add <data android:path="/fish/check"/>
  • consider pathPrefix, message path from "/check" to "/fish/check"

==phone module==

AndroidManifest.xml

...
         <service
            android:name=".wear.DataLayerListenerService"
            android:exported="true">
            <intent-filter>
                <action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
                <data
                    android:host="*"
                    android:pathPrefix="/fish"
                    android:scheme="wear" />
            </intent-filter>
        </service>
...

DataLayerListenerSerice.java

public class DataLayerListenerService extends WearableListenerService {
...
  @Override
  public void onMessageReceived(MessageEvent event){
    // receive msg command and sending back to watch.
    Timber.tag(TAG).e("DataLayerListenerService:onMessageReceived:%s", path);
    if(event.getPath()=="/fish/check"){
      WearManager.INSTANCE.sendCommand(getBaseContext(),"/fish/ready");
    }
  }
...
}

WearManager.kt

object WearManager{
...
  fun sendCommand(context:Context,path:String,msg:String=""){
    Wearable.getCapabilityClient(context)
            .getCapability("fish_capability", CapabilityClient.FILTER_REACHABLE)
            .addOnSuccessListener { capabilityInfo: CapabilityInfo ->
                if (capabilityInfo.nodes.isNotEmpty()) {
                    pickBestNodeId(capabilityInfo.nodes)?.let { node ->
                        Wearable.getMessageClient(context).sendMessage(node, path, msg.toByteArray())
                            .addOnSuccessListener {
                                Timber.tag(TAG).i("WearManager:sendCommand:ok")
                            }
                            .addOnFailureListener {
                                Timber.tag(TAG).e("WearManager:sendCommand:fail $it")
                            }
                    }
                } else {
                    Timber.tag(TAG).e("WearManager:sendCommand:nodes empty")
                }
            }
  }
...
}

==watch module==

AndroidManifest.xml

...
        <service
            android:name=".service.WearDataLayerService"
            android:exported="true">
            <intent-filter>
                <action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
                <action android:name="com.google.android.gms.wearable.CAPABILITY_CHANGED" />

                <data
                    android:host="*"
                    android:pathPrefix="/fish"
                    android:scheme="wear" />
            </intent-filter>
        </service>
...

WearDataLayerService.kt

class WearDataLayerService : WearableListenerService() {
...
    override fun onMessageReceived(msg: MessageEvent) {
        super.onMessageReceived(msg)
        Timber.tag(TAG).i("Service:onMessageReceived: ${msg.path}")
    }
...
}

MainActivity.kt

class MainActivity : AppCompatActivity(),MessageClient.OnMessageReceivedListener{
...
    override fun onResume() {
        super.onResume()
        Wearable.getMessageClient(this).addListener(this)
        startTimer()//run every second
    }
    override fun onPause() {
        super.onPause()
        Wearable.getMessageClient(this).removeListener(this)
        stopTimer()
    }
    private fun startTimer() {
        timer = Timer()
        timer?.run {
            schedule(object : TimerTask() {
                override fun run() {
                    send(CHECK) { //CHECK = "/fish/check"
                      Timber.tag(TAG).e("MainActivity:run: send $CHECK")
                    }
                }
            }, 0, 1000)
        }
    }
    override fun onMessageReceived(messageEvent: MessageEvent) {
        when (messageEvent.path) {
            "/fish/error"-> Timber.tag(TAG).e("msgReceived: fish error.")
            "/fish/ready"-> Timber.tag(TAG).e("msgReceived: fish ready")
        }
    }
    //nodeId updates from Wearable.getCapability...
    override fun send(path: String, message: String, callback: (id: String) -> Unit) {
        nodeId?.let { id ->
            Wearable.getMessageClient(this).sendMessage(id, path, message.toByteArray())
            callback(id)
        }
    }
...
}

device

  • samsung A71 (android 12) pair WearAVD (android 11.0)

  • Xiaomi Mi MIX 3 (android 10) pair Fossil Julianna HR (android 9)

0 Answers
Related