You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

从Android Wear向Android手机传输运动传感器数据的技术实现问询

Android Wear传感器数据传输到手机的实现方案

嘿,我来帮你梳理清楚这个问题~你提到的“无需在Wear端安装带UI的应用”是可以实现的,但确实必须在Wear端部署一个后台Service(完全不需要Activity/UI),这是Wear OS的系统限制决定的,下面给你详细拆解:

核心原因:为什么必须要有Wear端组件?

Wear OS的传感器硬件(加速度计、陀螺仪)只能由运行在Wear设备本地的进程访问——手机端的任何API(包括Play Services的Wear相关库)都没法直接跨设备读取Wear的传感器数据。Play Services提供的Wearable.DataClient/MessageClient只是通信通道,负责把Wear端本地获取到的数据传到手机,而不是直接读取硬件。

最简实现方案(Wear端仅用Service)

1. Wear端:前台Service获取并传输传感器数据

因为Wear OS对后台Service的限制很严,建议用前台Service(需要显示一个简单的通知栏,防止被系统杀死):

  • 创建Wear端模块,不需要添加Activity,只写一个继承自Service的类
  • 在Service中初始化SensorManager,注册加速度计(Sensor.TYPE_ACCELEROMETER)和陀螺仪(Sensor.TYPE_GYROSCOPE)的监听
  • 每次传感器回调触发时,把数据打包成DataMap,通过Wearable.DataClient.putDataItem()发送到手机

示例代码片段(Wear端Service):

class SensorDataService : Service() {
    private lateinit var sensorManager: SensorManager
    private lateinit var dataClient: Wearable.DataClient

    override fun onCreate() {
        super.onCreate()
        // 初始化传感器管理器
        sensorManager = getSystemService(SENSOR_SERVICE) as SensorManager
        // 初始化Wear数据客户端
        dataClient = Wearable.getDataClient(this)
        // 启动前台服务(必须,否则会被系统回收)
        startForeground(1, NotificationCompat.Builder(this, "sensor_channel")
            .setContentTitle("传感器数据传输中")
            .setSmallIcon(R.drawable.ic_notification)
            .build())
        // 注册传感器监听
        val accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
        val gyroscope = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE)
        sensorManager.registerListener(sensorListener, accelerometer, SensorManager.SENSOR_DELAY_NORMAL)
        sensorManager.registerListener(sensorListener, gyroscope, SensorManager.SENSOR_DELAY_NORMAL)
    }

    private val sensorListener = object : SensorEventListener {
        override fun onSensorChanged(event: SensorEvent) {
            val dataMap = DataMap().apply {
                putLong("timestamp", System.currentTimeMillis())
                putFloatArray("values", event.values)
                putInt("sensor_type", event.sensor.type)
            }
            // 构建数据项请求,发送到手机
            val request = PutDataMapRequest.create("/sensor-data").run {
                dataMap.putAll(dataMap)
                asPutDataRequest().setUrgent()
            }
            dataClient.putDataItem(request)
        }

        override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
    }

    override fun onBind(intent: Intent?): IBinder? = null
}

别忘了在Wear端的AndroidManifest.xml中声明权限和Service:

<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.wearable.permission.RECEIVE_DATA" />

<application>
    <service
        android:name=".SensorDataService"
        android:foregroundServiceType="dataSync">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </service>
</application>

2. 手机端:接收并处理传感器数据

手机端只需要用Wearable.DataClient监听Wear端发送的数据即可:

class SensorDataReceiver : LifecycleObserver {
    private lateinit var dataClient: Wearable.DataClient
    private var dataListener: DataClient.OnDataChangedListener? = null

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun startListening() {
        dataClient = Wearable.getDataClient(applicationContext)
        dataListener = DataClient.OnDataChangedListener { dataEvents ->
            for (event in dataEvents) {
                if (event.type == DataEvent.TYPE_CHANGED && event.dataItem.uri.path == "/sensor-data") {
                    val dataMap = DataMapItem.fromDataItem(event.dataItem).dataMap
                    val timestamp = dataMap.getLong("timestamp")
                    val values = dataMap.getFloatArray("values")
                    val sensorType = dataMap.getInt("sensor_type")
                    // 在这里处理收到的传感器数据(比如存储、展示)
                }
            }
        }
        dataClient.addListener(dataListener!!)
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun stopListening() {
        dataListener?.let { dataClient.removeListener(it) }
    }
}

然后在手机端的Activity或Application中注册这个观察者即可。

额外优化建议

  • 调整传感器采样频率:根据需求选择SENSOR_DELAY_NORMAL/SENSOR_DELAY_GAME等,避免高频传输导致Wear设备耗电过快
  • 数据压缩:可以用Protobuf代替DataMap序列化数据,减少传输体积
  • 连接稳定性:监听Wear设备的连接状态,当设备断开时暂停数据处理,重连后恢复
  • 自动启动Service:可以在Wear端监听BOOT_COMPLETED广播,设备重启后自动启动传感器Service

内容的提问来源于stack exchange,提问作者Daksh

火山引擎 最新活动