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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 16:05:29