Recently we noticed that messages sent from our wear app to the phone through MessageClient don't trigger the WearableListenerService start in some cases.
One of the cases in which it can be reproduced is when the phone app is force stopped. Once the phone app is force stopped once, the WearableListenerService will never start, even if we have the app opened on the screen.
We don't understand exactly what is missing, because before force stopping the phone app the messages are received correctly without any failure. We also tried to use the MessageClient inside an Activity, where it works perfectly after phone app restart. Looks like the problem has to do with the Service declaration.
¿Do you have any tips on what might be missing in the Service declaration? ¿Is it possible that the mentioned case is a restriction that we cannot solve?
Note: This case only applies on messages sent from wear to phone. If we force stop wear app, the ListenerService is correctly started on wear.
If you think more information needs to be provided don't hesitate to ask. Additionally, I am sorry if I am not expressing correctly in English.
Here is an example of the code related to the messages sent from wear to phone:
- Service declaration on Manifest:
<service
android:name=".DataLayerListenerService"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
<data
android:host="*"
android:pathPrefix="/start-activity-app"
android:scheme="wear" />
</intent-filter>
</service>
- WearableListenerService:
package com.example.android.wearable.datalayer
import android.content.Intent
import android.util.Log
import com.google.android.gms.wearable.MessageEvent
import com.google.android.gms.wearable.WearableListenerService
class DataLayerListenerService : WearableListenerService() {
override fun onCreate() {
super.onCreate()
Log.d("POC", "Start service")
}
override fun onDestroy() {
super.onDestroy()
Log.d("POC", "Stop service")
}
override fun onMessageReceived(messageEvent: MessageEvent) {
super.onMessageReceived(messageEvent)
Log.d("POC", "I am receiving a message.")
when (messageEvent.path) {
START_ACTIVITY_PATH -> {
Log.d("POC", "The message is the expected one.")
startActivity(
Intent(this, MainActivity::class.java)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
)
}
}
}
companion object {
private const val START_ACTIVITY_PATH = "/start-activity-app"
}
}
- Wear method that invokes the app:
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.lifecycle.lifecycleScope
import com.google.android.gms.wearable.CapabilityClient
import com.google.android.gms.wearable.Node
import com.google.android.gms.wearable.Wearable
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.launch
import kotlinx.coroutines.tasks.await
//...
private val dataClient by lazy { Wearable.getDataClient(this) }
private val messageClient by lazy { Wearable.getMessageClient(this) }
private val capabilityClient by lazy { Wearable.getCapabilityClient(this) }
//...
private fun onQueryAppInitClicked() {
lifecycleScope.launch {
try {
val capabilityInfo = capabilityClient.getCapability("mobile", CapabilityClient.FILTER_REACHABLE).await()
capabilityInfo.nodes.forEach { node ->
messageClient.sendMessage(node.id, "/start-activity-app", null).await()
Log.d("POC", "Sended message to node " + node.displayName)
}
Log.d("POC", "---")
} catch (cancellationException: CancellationException) {
throw cancellationException
} catch (exception: Exception) {
Log.d(TAG, "Querying nodes failed: $exception")
}
}
}
//...