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
相关产品推荐
相关产品推荐

