我去开发一个
Android
应用程序与React-native
,然后将我的手机应用程序与穿戴应用程序链接。
所以我要去
wear
应用程序里看看我的手机上是否有互锁应用程序。
我参考了Android功能中的应用程序检测功能文档。
我根据文档描述将值添加到 'app/res/values/wear.xml' 和 'wear/res/values/wear.xml' 。
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:keep="@array/android_wear_capabilities">
<string-array name="android_wear_capabilities">
<item>sample_app</item>
</string-array>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:keep="@array/android_wear_capabilities">
<string-array name="android_wear_capabilities">
<item>sample_wear</item>
</string-array>
</resources>
我在手表应用程序中使用Capability Client检查了配对的手机上是否安装了手机应用程序。但是,穿戴应用程序没有检测到我的手机应用程序。
穿着/主要活动
package com.soundgym.watchos
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.util.Log
import androidx.core.view.doOnPreDraw
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.core.view.setPadding
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.lifecycleScope
import androidx.wear.phone.interactions.PhoneTypeHelper
import androidx.wear.remote.interactions.RemoteActivityHelper
import androidx.wear.widget.ConfirmationOverlay
import com.google.android.gms.tasks.Tasks
import com.google.android.gms.wearable.*
import com.soundgym.watchos.databinding.ActivityMainBinding
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.guava.await
import kotlinx.coroutines.launch
import kotlinx.coroutines.tasks.await
import kotlinx.coroutines.withContext
import kotlin.math.roundToInt
import kotlin.math.sqrt
class MainWearActivity : FragmentActivity(), CapabilityClient.OnCapabilityChangedListener {
private lateinit var binding: ActivityMainBinding
private lateinit var capabilityClient: CapabilityClient
private lateinit var nodeClient: NodeClient
private lateinit var remoteActivityHelper: RemoteActivityHelper
private var androidPhoneNodeWithApp: Node? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
capabilityClient = Wearable.getCapabilityClient(this.applicationContext)
nodeClient = Wearable.getNodeClient(this)
remoteActivityHelper = RemoteActivityHelper(this)
binding.informationTextView.text = getString(R.string.message_checking)
binding.remoteOpenButton.setOnClickListener {
openAppInStoreOnPhone()
}
if (resources.configuration.isScreenRound) {
binding.scrollingContentContainer.doOnPreDraw {
// Calculate the padding necessary to make the scrolling content fit in a square inscribed on a round
// screen.
it.setPadding((it.width / 2.0 * (1.0 - 1.0 / sqrt(2.0))).roundToInt())
}
}
}
override fun onPause() {
super.onPause()
Wearable.getCapabilityClient(this).removeListener(this, CAPABILITY_PHONE_APP)
}
override fun onResume() {
super.onResume()
Wearable.getCapabilityClient(this).addListener(this, CAPABILITY_PHONE_APP)
lifecycleScope.launch {
checkIfPhoneHasApp()
}
}
/*
* Updates UI when capabilities change (install/uninstall phone app).
*/
override fun onCapabilityChanged(capabilityInfo: CapabilityInfo) {
Log.d(TAG, "onCapabilityChanged(): $capabilityInfo")
// There should only ever be one phone in a node set (much less w/ the correct capability), so
// I am just grabbing the first one (which should be the only one).
androidPhoneNodeWithApp = capabilityInfo.nodes.firstOrNull()
updateUi()
}
private suspend fun checkIfPhoneHasApp() {
Log.d(TAG, "checkIfPhoneHasApp()")
try {
val capabilityInfo = capabilityClient
.getCapability(CAPABILITY_PHONE_APP, CapabilityClient.FILTER_REACHABLE)
.await()
Log.d(TAG, "Capability request succeeded.${capabilityInfo.nodes.size}")
withContext(Dispatchers.Main) {
// There should only ever be one phone in a node set (much less w/ the correct capability), so
// I am just grabbing the first one (which should be the only one).
androidPhoneNodeWithApp = capabilityInfo.nodes.firstOrNull()
updateUi()
}
} catch (cancellationException: CancellationException) {
// Request was cancelled normally
} catch (throwable: Throwable) {
Log.d(TAG, "Capability request failed to return any results. \n reason : ${throwable.message}")
}
}
private fun updateUi() {
val androidPhoneNodeWithApp = androidPhoneNodeWithApp
if (androidPhoneNodeWithApp != null) {
// TODO: Add your code to communicate with the phone app via
// Wear APIs (MessageClient, DataClient, etc.)
Log.d(TAG, "Installed")
binding.informationTextView.text =
getString(R.string.message_installed, androidPhoneNodeWithApp.displayName)
binding.remoteOpenButton.isInvisible = true
} else {
Log.d(TAG, "Missing")
binding.informationTextView.text = getString(R.string.message_missing)
binding.remoteOpenButton.isVisible = true
}
}
private fun openAppInStoreOnPhone() {
Log.d(TAG, "openAppInStoreOnPhone()")
val intent = when (PhoneTypeHelper.getPhoneDeviceType(applicationContext)) {
PhoneTypeHelper.DEVICE_TYPE_ANDROID -> {
Log.d(TAG, "\tDEVICE_TYPE_ANDROID")
// Create Remote Intent to open Play Store listing of app on remote device.
Intent(Intent.ACTION_VIEW)
.addCategory(Intent.CATEGORY_BROWSABLE)
.setData(Uri.parse(ANDROID_MARKET_APP_URI))
}
PhoneTypeHelper.DEVICE_TYPE_IOS -> {
Log.d(TAG, "\tDEVICE_TYPE_IOS")
// Create Remote Intent to open App Store listing of app on iPhone.
Intent(Intent.ACTION_VIEW)
.addCategory(Intent.CATEGORY_BROWSABLE)
.setData(Uri.parse(APP_STORE_APP_URI))
}
else -> {
Log.d(TAG, "\tDEVICE_TYPE_ERROR_UNKNOWN")
return
}
}
lifecycleScope.launch {
try {
remoteActivityHelper.startRemoteActivity(intent).await()
ConfirmationOverlay().showOn(this@MainWearActivity)
} catch (cancellationException: CancellationException) {
// Request was cancelled normally
throw cancellationException
} catch (throwable: Throwable) {
ConfirmationOverlay()
.setType(ConfirmationOverlay.FAILURE_ANIMATION)
.showOn(this@MainWearActivity)
}
}
}
companion object {
private const val TAG = "MainWearActivity"
// Name of capability listed in Phone app's wear.xml.
// IMPORTANT NOTE: This should be named differently than your Wear app's capability.
private const val CAPABILITY_PHONE_APP = "sample_app"
// Links to install mobile app for both Android (Play Store) and iOS.
// TODO: Replace with your links/packages.
private const val ANDROID_MARKET_APP_URI = "market://details?id=com.sample.app"
// TODO: Replace with your links/packages.
private const val APP_STORE_APP_URI = "https://apps.apple.com/kr/app/com/id11111115"
}
}
为什么我检测不到???
问题原因是手机app的包名和手表app的包名不一样。该名称必须相同才能读取信息。
注意:对于
项目,应进行相同的更改 设为React-native
,因为有默认的wear app
。sign key for debug
磨损/build.gradle
signingConfigs {
debug {
storeFile file('../app/debug.keystore')
storePassword 'signingConfigs storePassword of app/build.gradle'
keyAlias 'signingConfigs keyAlias of app/build.gradle'
keyPassword 'signingConfigs keyPassword of app/build.gradle'
}
}