You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Jetpack Compose场景下,通过Alarm触发传感器监听后onSensorChanged无限循环且无法更新UI的问题求助

Android Jetpack Compose场景下,通过Alarm触发传感器监听后onSensorChanged无限循环且无法更新UI的问题求助

我是Android新手,完全不敢预设自己懂什么!之前我写了一段代码,用SensorEventListener结合MutableDoubleState来更新UI,当时把传感器注册成REPORTING_MODE_ON_CHANGE,运行得很正常。

但现在我需要实现每隔几分钟,在设备息屏/休眠状态下触发一次传感器读取并更新UI,所以改成用Alarm来实现:用setExactAndAllowWhileIdle设置了闹钟,也成功触发了BroadcastReceiver的onReceive方法。在onReceive里,我把传感器注册成REPORTING_MODE_ONE_SHOT,而且同一个类同时实现了BroadcastReceiver和SensorEventListener。

目前的状况是:传感器确实能触发onSensorChanged,但我用之前那套方法更新UI完全没效果,而且onSensorChanged还陷入了无限循环,根本没机会更新UI。我看到有资料说可能是线程问题,但我搞不懂为什么和之前的情况不一样,也没找到解决办法。另外我的UI是用Composable写的(应该是Jetpack Compose?跟着教程学的,教程没讲太清楚)。

下面是我的代码,希望能帮大家定位问题:

package com.scratch.pressurektv1

import android.app.Activity.SENSOR_SERVICE
import android.app.AlarmManager
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
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.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableDoubleState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import com.scratch.pressurektv1.ui.theme.PressureKTV1Theme
import kotlin.system.exitProcess
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableDoubleStateOf
import androidx.compose.runtime.remember
//import androidx.compose.runtime.livedata.observeAsState // Import the extension function
import androidx.lifecycle.MutableLiveData

//class TimePressureTuple(time: ZonedDateTime, pressure: Double)

class Support {
    companion object {
        var pressureReading: MutableDoubleState? = null
    }
}

class MyReceiver() : BroadcastReceiver(), SensorEventListener {
    override fun onReceive(context: Context?, intent: Intent?) {
        val sensorManager = context?.getSystemService(SENSOR_SERVICE) as SensorManager
        val pressureSensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE)
        Log.d("alarmManager", "Alarm went off")
        Support.pressureReading?.doubleValue = 999.9
        sensorManager.registerListener (this, pressureSensor, Sensor.REPORTING_MODE_ONE_SHOT)
    }

    override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
        Log.d("alarmManager", "onAccuracyChanged")
    }

    override fun onSensorChanged(event: SensorEvent?) {
        Log.d("alarmManager", "onSensorChanged")
        // code attempting to update UI removed
    }
}

class MainActivity : ComponentActivity() {
    private val pressureReading = mutableDoubleStateOf(1.0)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val mSensorManager: SensorManager = getSystemService(SENSOR_SERVICE) as SensorManager
        val pressureSensor: Sensor? = mSensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE)
        if (pressureSensor == null) exitProcess(1) // TODO -- helpful message would be good here!

        val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
        alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 1_000,
            PendingIntent.getBroadcast(this@MainActivity, 1234,
                Intent(this, MyReceiver::class.java), PendingIntent.FLAG_IMMUTABLE))

        enableEdgeToEdge()
        setContent {
            PressureKTV1Theme {
                Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
                    Greeting(
                        pressureReading, modifier = Modifier.padding(innerPadding)
                    )
                }
            }
        }
    }
}

@Composable
fun Greeting(data: MutableDoubleState, modifier: Modifier = Modifier) {
    val value by remember { data }
    Text(
        text = "Value is " + data.doubleValue,
        modifier = modifier
    )
}
<?xml version="1.0" encoding="utf-8"?>
<!-- 你提供的Manifest内容不完整,以下是已给出的部分 -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.scratch.pressurektv1">
    <!-- 剩余Manifest配置内容未提供 -->
</manifest>

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 10:58:04