我正在尝试为播放器应用程序添加蓝牙投射功能。
我正在连接配对的蓝牙音箱。蓝牙管理器我是这样的:
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)
}
}
}