Android使用registerForActivityResult()配对蓝牙设备遇问题求助
解决蓝牙配对registerForActivityResult崩溃及对象为空问题
1. 先搞定崩溃:正确注册ActivityResultContract
registerForActivityResult必须在页面进入STARTED状态前完成注册,不能等点击事件触发才去注册。在Compose里直接用rememberLauncherForActivityResult,它会自动绑定Compose的生命周期,保证注册时机没问题:
// 写在Compose组件的顶层,别塞到点击事件里 val bluetoothPairLauncher = rememberLauncherForActivityResult( contract = ActivityResultContracts.StartIntentSenderForResult() ) { result -> // 配对结果处理逻辑 if (result.resultCode == Activity.RESULT_OK) { // 配对成了,搞后续操作 } else { // 配对失败或者用户取消了 } }
要是用单独的配对Activity,就得在onCreate方法里注册,绝对不能放在onResume或者点击事件里:
class PairingActivity : AppCompatActivity() { private lateinit var bluetoothPairLauncher: ActivityResultLauncher<IntentSenderRequest> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 必须在onCreate里注册,早注册早安心 bluetoothPairLauncher = registerForActivityResult( ActivityResultContracts.StartIntentSenderForResult() ) { result -> // 处理配对结果 } // 其他初始化代码该咋写咋写 } // 触发配对的方法 fun startPairing(intentSender: IntentSender) { bluetoothPairLauncher.launch(IntentSenderRequest.Builder(intentSender).build()) } }
2. 解决btToPair为空的问题
这个大概率是状态没存对或者传错了:
- 要是从别的页面传蓝牙设备,直接用Parcelable传,BluetoothDevice本身支持这个:
// 跳配对页的时候传 val intent = Intent(context, PairingActivity::class.java).apply { putExtra("BLUETOOTH_DEVICE", btToPair) } // 配对页里取 val btToPair = intent.getParcelableExtra<BluetoothDevice>("BLUETOOTH_DEVICE") - 在Compose组件里,用
remember或者ViewModel存btToPair,别让重组给搞没了:// Compose组件里 val btToPair = remember { viewModel.currentBluetoothDevice // 从ViewModel拿或者传进来的参数 } // 点击按钮触发配对 Button(onClick = { btToPair?.let { device -> // 按官方逻辑拿IntentSender val pairingIntent = device.createBond() val intentSenderRequest = IntentSenderRequest.Builder(pairingIntent.intentSender).build() bluetoothPairLauncher.launch(intentSenderRequest) } }) { Text("开始配对") }
3. 配对触发时机要卡准生命周期
要是配对流程在onResume之后触发,别直接在onResume里启动配对,Compose里用LaunchedEffect,Activity里用postDelayed,确保launcher已经注册完再触发:
// Compose里这么写 LaunchedEffect(Unit) { // 页面启动后再触发配对,保证launcher已经注册好了 btToPair?.let { device -> val pairingIntent = device.createBond() val intentSenderRequest = IntentSenderRequest.Builder(pairingIntent.intentSender).build() bluetoothPairLauncher.launch(intentSenderRequest) } }
内容的提问来源于stack exchange,提问作者look_up
相关产品推荐
相关产品推荐

