Skip to content

Commit 86b81ba

Browse files
committed
Updates remote launch from Wear OS
1 parent 1aea393 commit 86b81ba

File tree

5 files changed

+69
-10
lines changed

5 files changed

+69
-10
lines changed

app/src/main/res/values/wear.xml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
Copyright 2025 The Android Open Source Project
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
https://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
-->
17+
<resources xmlns:tools="http://schemas.android.com/tools" tools:keep="@array/android_wear_capabilities">
18+
<string-array name="android_wear_capabilities">
19+
<item>androidify_phone</item>
20+
</string-array>
21+
</resources>

watchface/src/main/java/com/android/developers/androidify/watchface/transfer/WearDeviceRepository.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ package com.android.developers.androidify.watchface.transfer
1919

2020
import android.content.Context
2121
import com.android.developers.androidify.wear.common.ConnectedWatch
22-
import com.android.developers.androidify.wear.common.WearableConstants.ANDROIDIFY_INSTALLED
22+
import com.android.developers.androidify.wear.common.WearableConstants.ANDROIDIFY_INSTALLED_WEAR
2323
import com.google.android.gms.wearable.CapabilityClient
2424
import com.google.android.gms.wearable.Node
2525
import com.google.android.gms.wearable.NodeClient
@@ -56,7 +56,7 @@ class WearDeviceRepositoryImpl @Inject constructor(
5656
val allDevices = nodeClient.connectedNodes.await().toSet()
5757
val reachableCapability =
5858
capabilityClient.getCapability(
59-
ANDROIDIFY_INSTALLED,
59+
ANDROIDIFY_INSTALLED_WEAR,
6060
CapabilityClient.FILTER_REACHABLE,
6161
)
6262
.await()
@@ -70,7 +70,7 @@ class WearDeviceRepositoryImpl @Inject constructor(
7070

7171
trySend(selectConnectedDevice(installedDevicesUpdated, allDevices))
7272
}
73-
capabilityClient.addListener(capabilityListener, ANDROIDIFY_INSTALLED)
73+
capabilityClient.addListener(capabilityListener, ANDROIDIFY_INSTALLED_WEAR)
7474
} else {
7575
trySend(null)
7676
}

wear/common/src/main/java/com/android/developers/androidify/wear/common/WatchFaceInstallationStatus.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ sealed class WatchFaceInstallationStatus() {
4545
val activationStrategy: WatchFaceActivationStrategy,
4646
) : WatchFaceInstallationStatus()
4747

48-
object Preparing: WatchFaceInstallationStatus()
48+
object Preparing : WatchFaceInstallationStatus()
4949

5050
object Sending : WatchFaceInstallationStatus()
5151

wear/common/src/main/java/com/android/developers/androidify/wear/common/WearableConstants.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ object WearableConstants {
1919
const val ANDROIDIFY_INITIATE_TRANSFER_PATH = "/initiate_transfer"
2020
const val ANDROIDIFY_FINALIZE_TRANSFER_TEMPLATE = "/finalize_transfer/%s"
2121

22-
const val ANDROIDIFY_INSTALLED = "androidify"
22+
const val ANDROIDIFY_INSTALLED_WEAR = "androidify"
23+
const val ANDROIDIFY_INSTALLED_PHONE = "androidify_phone"
2324
const val ANDROIDIFY_TRANSFER_PATH_TEMPLATE = "/transfer_apk/%s"
2425

2526
const val SETUP_TIMEOUT_MS = 60_000L

wear/src/main/java/com/android/developers/androidify/LaunchOnPhoneActivity.kt

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,16 @@ import android.os.Bundle
2020
import android.util.Log
2121
import androidx.activity.ComponentActivity
2222
import androidx.core.net.toUri
23+
import androidx.lifecycle.lifecycleScope
2324
import androidx.wear.remote.interactions.RemoteActivityHelper
2425
import androidx.wear.widget.ConfirmationOverlay
2526
import androidx.wear.widget.ConfirmationOverlay.OPEN_ON_PHONE_ANIMATION
27+
import com.android.developers.androidify.wear.common.WearableConstants.ANDROIDIFY_INSTALLED_PHONE
28+
import com.google.android.gms.wearable.CapabilityClient
29+
import com.google.android.gms.wearable.Wearable
2630
import kotlinx.coroutines.guava.await
27-
import kotlinx.coroutines.runBlocking
31+
import kotlinx.coroutines.launch
32+
import kotlinx.coroutines.tasks.await
2833

2934
/**
3035
* A helper activity that launches the phone Androidify app. This Activity is only started from the
@@ -34,8 +39,6 @@ class LaunchOnPhoneActivity : ComponentActivity() {
3439
override fun onCreate(savedInstanceState: Bundle?) {
3540
super.onCreate(savedInstanceState)
3641

37-
val intent = Intent(Intent.ACTION_VIEW, "androidify://launch".toUri())
38-
intent.addCategory(Intent.CATEGORY_BROWSABLE)
3942
val helper = RemoteActivityHelper(this)
4043
val message: CharSequence = getString(R.string.continue_on_phone)
4144

@@ -48,7 +51,14 @@ class LaunchOnPhoneActivity : ComponentActivity() {
4851
}
4952
.showOn(this)
5053

51-
runBlocking {
54+
lifecycleScope.launch {
55+
val phoneNodeId = getConnectedAndroidifyNodeId()
56+
val intent = if (phoneNodeId != null) {
57+
getAndroidifyIntent()
58+
} else {
59+
getPlayIntent()
60+
}
61+
5262
try {
5363
helper.startRemoteActivity(intent).await()
5464
} catch (e: RemoteActivityHelper.RemoteIntentException) {
@@ -57,7 +67,34 @@ class LaunchOnPhoneActivity : ComponentActivity() {
5767
}
5868
}
5969

60-
fun onAnimationFinished() {
70+
private suspend fun getConnectedAndroidifyNodeId(): String? {
71+
val capabilityClient = Wearable.getCapabilityClient(this)
72+
73+
val capabilities = capabilityClient.getCapability(
74+
ANDROIDIFY_INSTALLED_PHONE,
75+
CapabilityClient.FILTER_REACHABLE,
76+
)
77+
.await()
78+
return if (capabilities.nodes.isNotEmpty()) {
79+
capabilities.nodes.first().id
80+
} else {
81+
null
82+
}
83+
}
84+
85+
private fun getPlayIntent(): Intent {
86+
val intent = Intent(Intent.ACTION_VIEW, "market://details?id=$packageName".toUri())
87+
intent.addCategory(Intent.CATEGORY_BROWSABLE)
88+
return intent
89+
}
90+
91+
private fun getAndroidifyIntent(): Intent {
92+
val intent = Intent(Intent.ACTION_VIEW, "androidify://launch".toUri())
93+
intent.addCategory(Intent.CATEGORY_BROWSABLE)
94+
return intent
95+
}
96+
97+
private fun onAnimationFinished() {
6198
finish()
6299
}
63100
}

0 commit comments

Comments
 (0)