Reputation: 13
I am trying to write a companion app to push a Play Store link from phone to wear OS watch to install my watch face. I have this function that is called when a button is pressed. It is supposed to get the nodeID for the wear OS device and push the link to the wear OS device. When I put my phone in Wireless Debugging mode with Android Studio and run the app on the my phone (which is connected to my watch), the button appears responsive, and the toast messages display, but nothing happens on my watch. I added a toast message to display the nodeID and it returns as "null," leading me to believe the portion of code that is supposed to retrieve the nodeID is not working. There are no errors in Android Studio. Can anyone help me figure out why this code is not successfully getting the nodeID?
EDIT: After doing some more researching and debugging with Log messages, I have concluded that the code does successfully get the NodeID. The problem is that the RemoteActivityHelper runs before the phone has retrieved the NodeID. Logcat output for "getNode()1" successfully shows my connected watch, but it appears after RAH has run (and Log message for RAH contains "null" watchID variable). So I need to be able to delay the RAH from running until it has the Node. I've expanded my code to show both parts now. Any assistance in delaying RAH would be appreciated!
@Composable
fun InstallButton() {
val context = LocalContext.current
OutlinedButton(onClick = {
Log.d("InstallButton", "InstallButton pressed")
context.getNode()
}) {
Text("Install on Watch")
}
}
fun Context.getNode() {
var watchNode: Node? = null
val uri: String = "https://play.google.com/store/apps/details?id=com.watchfacestudio.sedona"
Log.d("GetNode()", "GetNode() function started")
// Creates a thread
Thread {
// Get all nodes (nodes are devices connected)
val nodeListTask: Task<List<Node>> =
Wearable.getNodeClient(applicationContext).connectedNodes
Log.d("getNodeClient", "node list:$nodeListTask")
try {
// Try to get the first node and assign it to the WATCH_NODE variable | Usually the first node is the watch, but, if you want, you can iterate all nodes (check google docs to see how to identify the watch)
watchNode = Tasks.await(nodeListTask)[0]
} catch (ignore: Exception) {
}
Log.d("getNode()1", "watchNode ID = $watchNode")
}.start()
Log.d("getNode()2", "watchNode ID = $watchNode")
// Creates the intent that we will pass to the watch
val i = Intent(Intent.ACTION_VIEW)
i.addCategory(Intent.CATEGORY_BROWSABLE)
// Creates the uri to the watchface/app | the string part is a standard deeplink to google play | Important: the watchface/watch app and the phone app, must have the same package name!!
// Possible alternative to remove need to manually specifying package name:
// i.setData(Uri.parse("market://details?id=" + getPackageName()))
i.data = Uri.parse(uri)
Log.d("Creating intent","URI=$uri")
// Create a remoteActivityHelper instance
val remoteActivityHelper = RemoteActivityHelper(this, Executors.newSingleThreadExecutor())
// Send the intent to the watch (node)
remoteActivityHelper.startRemoteActivity(i, watchNode?.id ?: "")
Log.d("remoteActivityHelper","watchNode ID: $watchNode")
// Just shows a message on the user phone
Toast.makeText(this, "Check your watch", Toast.LENGTH_SHORT).show()
}
Upvotes: 0
Views: 157
Reputation: 2548
This answer is in Java and works without needing the Capability String:
Task<List<Node>> nodeListTask = Wearable.getNodeClient(getApplicationContext()).getConnectedNodes();
nodeListTask.addOnSuccessListener(nodes -> {
for (Node node : nodes) {
if (node.isNearby()) {
String watchNodeId = node.getId();
helper.startRemoteActivity(intent, watchNodeId);
}
}
});
});
The code is a snippet from: https://github.com/bredlix/wf_companion_app/blob/master/app%2Fsrc%2Fmain%2Fjava%2Fcom%2Fandroid%2Fwf_companion_app%2FMainActivity.java#L74-L83
And works quite similarly to my previous answer (aside from the Capabilities)
Upvotes: 0
Reputation: 2548
Try looking at this example (it has since been removed from the google repo but is still reachable)
and specifically in this function openPlayStoreOnWearDevicesWithoutApp()
that is in the mobile app
nodesWithoutApp.forEach { node ->
lifecycleScope.launch {
try {
remoteActivityHelper
.startRemoteActivity(
targetIntent = intent,
targetNodeId = node.id
)
.await()
Toast.makeText(
this@MainMobileActivity,
getString(R.string.store_request_successful),
Toast.LENGTH_SHORT
).show()
}
Note that this function checks for a Capability name that can be put in the wear version of the app. Then you can verify that way if the wear app has been installed or not by checking for the Capability name
Upvotes: 0