我在 Jetpack Compose 应用程序中遇到一个问题,当蓝牙关闭时,
ACTION_STATE_CHANGED
广播接收器似乎被调用两次。我有一个可组合函数BluetoothStateListener,它注册一个广播接收器来侦听蓝牙状态的变化。但是,当我关闭蓝牙时,广播接收器的 onReceive 函数被调用两次,导致意外行为。
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
var isBluetoothEnable by remember { mutableStateOf(false) }
ScreenOne(isBluetoothEnable) { isBluetoothEnable = it }
}
}
}
@Composable
fun ScreenOne(isBluetoothEnable: Boolean, onBluetoothChange: (Boolean) -> Unit) {
Text(text = "Hello world isBluetoothEnable $isBluetoothEnable")
BluetoothStateListener {
onBluetoothChange(it)
Log.i("BluetoothStateListener", "isBluetoothEnable $it")
}
}
@Composable
fun BluetoothStateListener(
context: Context = LocalContext.current,
isBluetoothEnable: (Boolean) -> Unit
) {
DisposableEffect(Unit) {
val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (intent?.action == BluetoothAdapter.ACTION_STATE_CHANGED) {
val state =
intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)
isBluetoothEnable(state == BluetoothAdapter.STATE_ON)
}
}
}
val filter = IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)
context.registerReceiver(receiver, filter)
onDispose {
context.unregisterReceiver(receiver)
}
}
}
在打印日志中我可以看到日志函数正在打印值
2024-02-29 22:44:16.938 15425-15425 BluetoothStateListener com.example.simplecomposenavigation I isBluetoothEnable false
2024-02-29 22:44:17.215 15425-15425 BluetoothStateListener com.example.simplecomposenavigation I isBluetoothEnable true
您正在通过比较其状态来检查蓝牙是否已启用:
isBluetoothEnable(state == BluetoothAdapter.STATE_ON)
,而有多种状态:
public static final int STATE_OFF = 10;
public static final int STATE_ON = 12;
public static final int STATE_TURNING_OFF = 13;
public static final int STATE_TURNING_ON = 11;
如果您记录当前状态,您将得到类似以下内容:
state = 11
isBluetoothEnable false
state = 12
isBluetoothEnable true
state = 13
isBluetoothEnable false
state = 10
isBluetoothEnable false
这意味着您应该只检查 ON 和 OFF 状态,如下所示:
when (state) {
BluetoothAdapter.STATE_OFF -> isBluetoothEnable(false)
BluetoothAdapter.STATE_ON -> isBluetoothEnable(true)
else -> {}
}