WearOS 心率正在读取,但显示屏上没有变化

问题描述 投票:0回答:1

我正在开发一个wearos应用程序,它可以读取心率然后显示它。在手表上,应用程序显示“心率:0”并根据用户的心率进行更改。尽管我已将其设置为在日志猫上显示新的心率数据,以便我可以看到它,但它不会更新显示。当应该显示实际值时,显示屏仍显示“心率:0”。

我对使用 kotlin 和 compose 相当陌生,所以它非常混乱,我对我哪里出错了感到相当困惑。下面我附上了代码和一些图像。 Watch Display image Logcat image

MainActivity 代码

package com.example.myapplication.presentation

import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import androidx.wear.compose.material.MaterialTheme
import androidx.wear.compose.material.Text
import kotlinx.coroutines.launch

class MainActivity : ComponentActivity() {

    private lateinit var sensorManager: SensorManager
    private var heartRateSensor: Sensor? = null
    private var heartRateSensorListener: SensorEventListener? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
        heartRateSensor = sensorManager.getDefaultSensor(Sensor.TYPE_HEART_RATE)

        setContent {
            HeartRateApp()
        }
    }

    @Preview(device = Devices.WEAR_OS_SMALL_ROUND, showSystemUi = true)
    @Composable
    fun HeartRateApp() {
        var heartRate by remember { mutableStateOf(0) }

        Column(
            modifier = Modifier
                .fillMaxSize()
                .background(MaterialTheme.colors.background),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally


        ) {
            Text(
                text = "Heart Rate: $heartRate",
                textAlign = TextAlign.Center
            )

            LaunchedEffect(key1 = heartRateSensor) {
                startHeartRateUpdates()
            }
        }
    }

    private fun startHeartRateUpdates() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.BODY_SENSORS)
            != PackageManager.PERMISSION_GRANTED
        ) {
            ActivityCompat.requestPermissions(
                this,
                arrayOf(Manifest.permission.BODY_SENSORS),
                PERMISSION_REQUEST_BODY_SENSORS
            )
            return
        }

        val mutableHeartRate = mutableStateOf(0)

        heartRateSensorListener = object : SensorEventListener {
            override fun onSensorChanged(event: SensorEvent?) {
                event?.let {
                    if (it.sensor.type == Sensor.TYPE_HEART_RATE) {
                        val heartRateValue = it.values[0].toInt()
                        Log.d(TAG, "New Heart Rate Data: $heartRateValue")
                        mutableHeartRate.value = heartRateValue
                    }
                }
            }

            override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
                // Not needed for heart rate sensor
            }
        }

        sensorManager.registerListener(
            heartRateSensorListener,
            heartRateSensor,
            SensorManager.SENSOR_DELAY_NORMAL
        )

        // Observe changes in mutableHeartRate and update heartRate accordingly
        lifecycleScope.launch {
            updateHeartRate(mutableHeartRate.value)
        }
    }





    private fun updateHeartRate(heartRate: Int) {
        // Update the UI with the latest heart rate value
        Log.d(TAG, "Heart Rate: $heartRate")


    }

    override fun onDestroy() {
        super.onDestroy()
        heartRateSensorListener?.let {
            sensorManager.unregisterListener(it)
        }
    }

    companion object {
        private const val PERMISSION_REQUEST_BODY_SENSORS = 101
        private const val TAG = "HeartRateApp"
    }
}

提前感谢 sm 帮助我:)

android kotlin android-jetpack-compose wear-os
1个回答
0
投票

UI 似乎没有反映更新后的心率值。

您需要观察 mutableHeartRate 变量的变化并更新 HeartRateApp 可组合函数中的 heartRate 变量。在您的代码中,您仅启动一个协程来更新心率,但并未更新 UI 中使用的 heartRate 变量。

    @Preview(device = Devices.WEAR_OS_SMALL_ROUND, showSystemUi = true)
@Composable
fun HeartRateApp() {
    var heartRate by remember { mutableStateOf(0) }

    Column(
        modifier = Modifier
            .fillMaxSize()
            .background(MaterialTheme.colors.background),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(
            text = "Heart Rate: $heartRate",
            textAlign = TextAlign.Center
        )

        LaunchedEffect(key1 = heartRateSensor) {
            startHeartRateUpdates { newHeartRate ->
                heartRate = newHeartRate
            }
        }
    }
}

private fun startHeartRateUpdates(onHeartRateUpdated: (Int) -> Unit) {
    if (ContextCompat.checkSelfPermission(
            this,
            Manifest.permission.BODY_SENSORS
        ) != PackageManager.PERMISSION_GRANTED
    ) {
        ActivityCompat.requestPermissions(
            this,
            arrayOf(Manifest.permission.BODY_SENSORS),
            PERMISSION_REQUEST_BODY_SENSORS
        )
        return
    }

    heartRateSensorListener = object : SensorEventListener {
        override fun onSensorChanged(event: SensorEvent?) {
            event?.let {
                if (it.sensor.type == Sensor.TYPE_HEART_RATE) {
                    val heartRateValue = it.values[0].toInt()
                    Log.d(TAG, "New Heart Rate Data: $heartRateValue")
                    onHeartRateUpdated(heartRateValue)
                }
            }
        }

        override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
            // Not needed for heart rate sensor
        }
    }

    sensorManager.registerListener(
        heartRateSensorListener,
        heartRateSensor,
        SensorManager.SENSOR_DELAY_NORMAL
    )
}

private fun updateHeartRate(heartRate: Int) {
    // Update the UI with the latest heart rate value
    Log.d(TAG, "Heart Rate: $heartRate")
}
© www.soinside.com 2019 - 2024. All rights reserved.