断开蓝牙 a2dp 设备保持通话连接(真正的问题:它保持自动重新连接)

问题描述 投票:0回答:0

我正在尝试为播放器应用程序添加蓝牙投射功能。

我正在连接配对的蓝牙音箱。蓝牙管理器我是这样的:


    private val bluetoothManager by lazy {
        requireContext.getSystemService(BluetoothManager::class.java)
    }

    private val bluetoothAdapter by lazy {
        bluetoothManager?.adapter
    }

我的连接方式:

pairedDevicesAdapter.setOnItemClickListener { deviceToConnect ->

            device = deviceToConnect

            bluetoothAdapter?.getProfileProxy(
                requireContext,
                object : BluetoothProfile.ServiceListener{
                    override fun onServiceConnected(profile: Int, proxy: BluetoothProfile?) {

                        a2dp = proxy as BluetoothA2dp

                        try{
                            a2dp.javaClass
                                .getMethod("connect", BluetoothDevice::class.java)
                                .invoke(a2dp, device)
                        } catch (e : Exception) {
                            Log.d("CHECKTAGS", e.stackTraceToString())
                        }

                    }

                    override fun onServiceDisconnected(profile: Int) {

                        device?.let {
                            disConnectUsingBluetoothA2dp(it)
                        }

                    }
                }, BluetoothProfile.A2DP
            )

        }

和断开方法:

private fun disConnectUsingBluetoothA2dp(deviceToConnect: BluetoothDevice){

        try {

            a2dp.javaClass.getMethod(
                "disconnect",
                BluetoothDevice::class.java
            ).invoke(a2dp, deviceToConnect)
            bluetoothAdapter?.closeProfileProxy(BluetoothProfile.A2DP, a2dp)
    

        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

连接正常。但断开部分工作。在蓝牙设置中,它表示扬声器仍处于通话连接状态。

问题是如果我关闭再打开扬声器,它会自动连接音频,我的播放器会再次开始翻译扬声器上的音频。

我尝试了我在旧帖子中找到的其他断开连接的实现方法,但无论我做什么,设备都会保持其连接以进行呼叫。

更新

我猜问题不在于与呼叫的连接仍然存在。只是配对的设备在重新启动后会重新连接到手机(并自动再次用于音频)。即使它似乎与应用程序的断开连接功能完全断开连接(实际上在手机设置中断开连接也是如此)

我不知道这种蓝牙行为。有办法处理吗?我在寻找什么:如果我的应用程序正在运行,并且某些设备正在尝试自动连接,我会捕获连接请求并阻止它。但我只看到 ACTION_ACL_DISCONNECT_REQUESTED 事件。

有点用 ACTION_ACL_CONNECTED 来管理它。接收器返回连接设备:

class ConnectingDeviceReceiver(
    private val connectingDevice: (BluetoothDevice) -> Unit
): BroadcastReceiver() {

    override fun onReceive(context: Context?, intent: Intent?) {

        when(intent?.action) {
            BluetoothDevice.ACTION_ACL_CONNECTED -> {

                val device = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                    intent.getParcelableExtra(
                        BluetoothDevice.EXTRA_DEVICE,
                        BluetoothDevice::class.java
                    )
                } else {
                    intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)
                }
                device?.let(connectingDevice)
            }

        }
    }
}

然后我初始化接收器:

@SuppressLint("MissingPermission")
private val connectingDeviceReceiver = ConnectingDeviceReceiver { deviceToDisconnect ->
    
      disconnect(deviceToDisconnect)
    
}


    val filter = IntentFilter()
    filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED)
   context.registerReceiver(
    connectingDeviceReceiver,
   filter
)

当然,如果我在接收器被触发后立即调用断开连接功能,它不会做任何事情,它需要为此找到合适的时机。所以我需要继续断开连接才能让它工作。

而且我找不到任何方法来检测,当设备不再连接 a2dp 时......如果它始终为 false,则当断开功能成功时没有事件可听。而且由于设备保持通话连接,我也看不到它断开连接。

@SuppressLint("MissingPermission")
private fun disconnect(device: BluetoothDevice) {

    val serviceListener: BluetoothProfile.ServiceListener = object :
        BluetoothProfile.ServiceListener {
        override fun onServiceDisconnected(profile: Int) {}

        @SuppressLint("DiscouragedPrivateApi")
        override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) {


            val disconnect = BluetoothA2dp::class.java.getDeclaredMethod(
                "disconnect",
                BluetoothDevice::class.java
            )
            disconnect.isAccessible = true
            disconnect.invoke(proxy, device)
            bluetoothAdapter?.closeProfileProxy(profile, proxy)
        }
    }

    lifecycleScope.launch {
        while (true){
            delay(50)
            bluetoothAdapter?.getProfileProxy(context, serviceListener, BluetoothProfile.A2DP)
        }
    }
}
bluetooth android-bluetooth a2dp
© www.soinside.com 2019 - 2024. All rights reserved.