WearableListenerService receiving messages between phone and watch works fine, but sometimes not...
with below source code,
- Wear device will send "/fish/check" every second
- 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)