如何在 Jetpack Compose 中动态跟踪 BluetoothAdapter 状态变化?

How to track BluetoothAdapter state changes dynamically in Jetpack Compose?

在我的应用程序中,我想知道用户 enables/disables 蓝牙是否使用状态栏并显示 UI 的相关片段。为此,我认为我需要在我的 @Composable 函数中跟踪当前的 BluetoothAdapter.isEnabled 状态。这是我的:

class MainActivity : ComponentActivity() {

    private val bluetoothAdapter: BluetoothAdapter by lazy {
        val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
        bluetoothManager.adapter
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        var isBluetoothEnabled = bluetoothAdapter.isEnabled

        setContent {
            AppTheme {
                MainScreen(isBluetoothEnabled)
            }
        }
    }
}

@Composable
private fun MainScreen(
    isBluetoothEnabled: Boolean
) {
    if (isBluetoothEnabled) {
        // Display some UI
    } else {
        // Display different UI
    }
}

应用启动时,我可以获得应用的正确蓝牙状态,但由于 BluetoothAdapter.isEnabled 不是 @Composable 生命周期的一部分,我无法跟踪它之后对变化做出反应,就像它是一种反应状态。有什么方法可以实现我想要的行为吗?

我使用 mutableStateOf 就解决了这个问题。它不必在 @Composable 函数内部初始化即可响应,这是我首先误解的。

  1. 定义一个 mutableStateOf 值和一个 BroadcastReceiver 来跟踪 BluetoothAdapter 的状态。当蓝牙状态改变时,更新值。
    private var isBluetoothEnabled = mutableStateOf(false)

    private val mReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            if (intent?.action == BluetoothAdapter.ACTION_STATE_CHANGED) {
                when (intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)) {
                    BluetoothAdapter.STATE_OFF -> {
                        isBluetoothEnabled.value = false
                        Log.i("Bluetooth", "State OFF")
                    }
                    BluetoothAdapter.STATE_ON -> {
                        isBluetoothEnabled.value = true
                        Log.i("Bluetooth", "State ON")
                    }
                }

            }
        }
    }
  1. @Composable 函数内部,照常使用此值:
@Composable
private fun MainScreen(
    isBluetoothEnabled: Boolean
) {
    if (isBluetoothEnabled) {
        // Display some UI
    } else {
        // Display different UI
    }
}

就是这样!