diff --git a/app/src/main/res/values/wear.xml b/app/src/main/res/values/wear.xml new file mode 100644 index 00000000..828b9d71 --- /dev/null +++ b/app/src/main/res/values/wear.xml @@ -0,0 +1,21 @@ + + + + + androidify_phone + + diff --git a/watchface/src/main/java/com/android/developers/androidify/watchface/transfer/WearDeviceRepository.kt b/watchface/src/main/java/com/android/developers/androidify/watchface/transfer/WearDeviceRepository.kt index fde3e4da..bc033e45 100644 --- a/watchface/src/main/java/com/android/developers/androidify/watchface/transfer/WearDeviceRepository.kt +++ b/watchface/src/main/java/com/android/developers/androidify/watchface/transfer/WearDeviceRepository.kt @@ -19,7 +19,7 @@ package com.android.developers.androidify.watchface.transfer import android.content.Context import com.android.developers.androidify.wear.common.ConnectedWatch -import com.android.developers.androidify.wear.common.WearableConstants.ANDROIDIFY_INSTALLED +import com.android.developers.androidify.wear.common.WearableConstants.ANDROIDIFY_INSTALLED_WEAR import com.google.android.gms.wearable.CapabilityClient import com.google.android.gms.wearable.Node import com.google.android.gms.wearable.NodeClient @@ -56,7 +56,7 @@ class WearDeviceRepositoryImpl @Inject constructor( val allDevices = nodeClient.connectedNodes.await().toSet() val reachableCapability = capabilityClient.getCapability( - ANDROIDIFY_INSTALLED, + ANDROIDIFY_INSTALLED_WEAR, CapabilityClient.FILTER_REACHABLE, ) .await() @@ -70,7 +70,7 @@ class WearDeviceRepositoryImpl @Inject constructor( trySend(selectConnectedDevice(installedDevicesUpdated, allDevices)) } - capabilityClient.addListener(capabilityListener, ANDROIDIFY_INSTALLED) + capabilityClient.addListener(capabilityListener, ANDROIDIFY_INSTALLED_WEAR) } else { trySend(null) } diff --git a/wear/common/src/main/java/com/android/developers/androidify/wear/common/WatchFaceInstallationStatus.kt b/wear/common/src/main/java/com/android/developers/androidify/wear/common/WatchFaceInstallationStatus.kt index 70025bc4..39837d5d 100644 --- a/wear/common/src/main/java/com/android/developers/androidify/wear/common/WatchFaceInstallationStatus.kt +++ b/wear/common/src/main/java/com/android/developers/androidify/wear/common/WatchFaceInstallationStatus.kt @@ -45,7 +45,7 @@ sealed class WatchFaceInstallationStatus() { val activationStrategy: WatchFaceActivationStrategy, ) : WatchFaceInstallationStatus() - object Preparing: WatchFaceInstallationStatus() + object Preparing : WatchFaceInstallationStatus() object Sending : WatchFaceInstallationStatus() diff --git a/wear/common/src/main/java/com/android/developers/androidify/wear/common/WearableConstants.kt b/wear/common/src/main/java/com/android/developers/androidify/wear/common/WearableConstants.kt index b998b711..62b5ffc2 100644 --- a/wear/common/src/main/java/com/android/developers/androidify/wear/common/WearableConstants.kt +++ b/wear/common/src/main/java/com/android/developers/androidify/wear/common/WearableConstants.kt @@ -19,9 +19,13 @@ object WearableConstants { const val ANDROIDIFY_INITIATE_TRANSFER_PATH = "/initiate_transfer" const val ANDROIDIFY_FINALIZE_TRANSFER_TEMPLATE = "/finalize_transfer/%s" - const val ANDROIDIFY_INSTALLED = "androidify" + const val ANDROIDIFY_INSTALLED_WEAR = "androidify" + const val ANDROIDIFY_INSTALLED_PHONE = "androidify_phone" const val ANDROIDIFY_TRANSFER_PATH_TEMPLATE = "/transfer_apk/%s" + const val ANDROIDIFY_PLAY_URL = "market://details?id=" + const val ANDROIDIFY_LAUNCH_URL = "androidify://launch" + const val SETUP_TIMEOUT_MS = 60_000L const val TRANSFER_TIMEOUT_MS = 60_000L } diff --git a/wear/src/main/java/com/android/developers/androidify/LaunchOnPhoneActivity.kt b/wear/src/main/java/com/android/developers/androidify/LaunchOnPhoneActivity.kt index 56f7caa1..f38370a0 100644 --- a/wear/src/main/java/com/android/developers/androidify/LaunchOnPhoneActivity.kt +++ b/wear/src/main/java/com/android/developers/androidify/LaunchOnPhoneActivity.kt @@ -20,11 +20,18 @@ import android.os.Bundle import android.util.Log import androidx.activity.ComponentActivity import androidx.core.net.toUri +import androidx.lifecycle.lifecycleScope import androidx.wear.remote.interactions.RemoteActivityHelper import androidx.wear.widget.ConfirmationOverlay import androidx.wear.widget.ConfirmationOverlay.OPEN_ON_PHONE_ANIMATION +import com.android.developers.androidify.wear.common.WearableConstants.ANDROIDIFY_INSTALLED_PHONE +import com.android.developers.androidify.wear.common.WearableConstants.ANDROIDIFY_LAUNCH_URL +import com.android.developers.androidify.wear.common.WearableConstants.ANDROIDIFY_PLAY_URL +import com.google.android.gms.wearable.CapabilityClient +import com.google.android.gms.wearable.Wearable import kotlinx.coroutines.guava.await -import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.launch +import kotlinx.coroutines.tasks.await /** * A helper activity that launches the phone Androidify app. This Activity is only started from the @@ -34,8 +41,6 @@ class LaunchOnPhoneActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - val intent = Intent(Intent.ACTION_VIEW, "androidify://launch".toUri()) - intent.addCategory(Intent.CATEGORY_BROWSABLE) val helper = RemoteActivityHelper(this) val message: CharSequence = getString(R.string.continue_on_phone) @@ -48,7 +53,14 @@ class LaunchOnPhoneActivity : ComponentActivity() { } .showOn(this) - runBlocking { + lifecycleScope.launch { + val phoneNodeId = getConnectedAndroidifyNodeId() + val intent = if (phoneNodeId != null) { + getAndroidifyIntent() + } else { + getPlayIntent() + } + try { helper.startRemoteActivity(intent).await() } catch (e: RemoteActivityHelper.RemoteIntentException) { @@ -57,7 +69,30 @@ class LaunchOnPhoneActivity : ComponentActivity() { } } - fun onAnimationFinished() { + private suspend fun getConnectedAndroidifyNodeId(): String? { + val capabilityClient = Wearable.getCapabilityClient(this) + + val capabilities = capabilityClient.getCapability( + ANDROIDIFY_INSTALLED_PHONE, + CapabilityClient.FILTER_REACHABLE, + ) + .await() + return capabilities.nodes.firstOrNull()?.id + } + + private fun getPlayIntent(): Intent { + val intent = Intent(Intent.ACTION_VIEW, "$ANDROIDIFY_PLAY_URL$packageName".toUri()) + intent.addCategory(Intent.CATEGORY_BROWSABLE) + return intent + } + + private fun getAndroidifyIntent(): Intent { + val intent = Intent(Intent.ACTION_VIEW, ANDROIDIFY_LAUNCH_URL.toUri()) + intent.addCategory(Intent.CATEGORY_BROWSABLE) + return intent + } + + private fun onAnimationFinished() { finish() } }