Reputation: 311
I am trying to get a mobile app to show a companion app on a connected Wear device.
Goal
When a simple countdown timer is started a message is sent to connected wear device(s) and they show the same countdown as the mobile
Problem
When the Wear device is in Ambient Mode startActivity() does not result in the Wear Device exiting Ambient Mode and the count down is not shown
Code which receives message but does not show App ...
For the Wear App to receive messages from the mobile it is implemented as a service
class DataLayerListenerService : WearableListenerService() {
private lateinit var messageClient : MessageClient
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
override fun onCreate() {
messageClient = Wearable.getMessageClient(this)
messageClient.addListener {
Log.d(TAG, "service OnMessageReceived ${it.path}")
if (it.path.equals(START_ACTIVITY_PATH, true)) {
Log.d(TAG, "service OnMessageReceived -> startActivity()")
startActivity(
Intent(this, MainWearActivity::class.java)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)
)
}
}
}
override fun onDestroy() {
super.onDestroy()
messageClient.removeListener { }
scope.cancel()
}
companion object {
private const val TAG = "MainWearActivity"
private const val START_ACTIVITY_PATH = "/start-activity"
}
}
The WearableListenerService is then included in the Wear Manifest file
<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"
android:scheme="wear" />
</intent-filter>
</service>
So the code works perfectly provided the Wear device is not in Ambient mode. When the message is received the specified App is brought to the foreground (it does not even need to have been run previously)
Unfortunately if the Wear device is in Ambient mode then while the log shows the message being received, the device does not exit Ambient mode and the specified app is not shown
I have tried different Intents but so far none have brought the Wear device out of Ambient Mode
Intent(this, MainWearActivity::class.java)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)
For completeness the code on the mobile device:
private fun startWearableActivity() {
lifecycleScope.launch {
try {
val connectedNodes = nodeClient.connectedNodes.await()
writeToLog("startWearableActivity() found ${connectedNodes.count()} connected nodes")
connectedNodes.map { node ->
writeToLog("startWearableActivity() - Trying to sendMessage to node ${node.displayName}")
async {
// TODO : add countdown value to the byteArrayOf()
messageClient.sendMessage(node.id, START_ACTIVITY_PATH, byteArrayOf()).await()
}
}.awaitAll()
writeToLog("startWearableActivity() - All activity start requests sent successfully")
} catch (cancellationException: CancellationException) {
writeToLog("startWearableActivity() - Start requests cancelled normally")
} catch (exception: Exception) {
writeToLog("startWearableActivity() - Activity start requests failed!!! Exception : $exception")
}
}
}
When run the log shows "All activity start requests sent successfully"
It appears the only work around is to stop the Wear App going into Ambient Mode
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
So is it possible for the mobile to send a message to the Wear device and have it exit Ambient Mode?
Upvotes: 1
Views: 312
Reputation: 13488
It's documented here.
I think you'll need to use WearableListenerService.
abstract class WearDataService : WearableListenerService() {
override fun onMessageReceived(p0: MessageEvent) {
//
}
}
<service
android:name="my.WearDataService"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
<data
android:host="*"
android:pathPrefix="/proto/"
android:scheme="wear" />
</intent-filter>
</service>
Upvotes: 0