diff --git a/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/BleMediaService.kt b/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/BleMediaService.kt index ea127ffb1..d1b8a1827 100644 --- a/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/BleMediaService.kt +++ b/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/BleMediaService.kt @@ -247,31 +247,37 @@ private var companionManager: BleCompanionManager? = null * 检查已连接的蓝牙设备 * 在服务启动或蓝牙开启时调用,检查是否有目标设备已经连接 */ + // 方法:checkAlreadyConnectedDevices private fun checkAlreadyConnectedDevices() { try { bluetoothAdapter?.let { adapter -> - if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_CONNECT) - == PackageManager.PERMISSION_GRANTED) { - - val bondedDevices = adapter.bondedDevices - Log.i(TAG, "检查已绑定的设备数量: ${bondedDevices?.size ?: 0}") - - bondedDevices?.forEach { device -> - val deviceName = device.name ?: "Unknown" - Log.d(TAG, "已绑定设备: $deviceName (${device.address})") - - if (deviceName.equals(TARGET_DEVICE_NAME, ignoreCase = true)) { - Log.i(TAG, "发现已绑定的目标设备: $deviceName") - val pairedUuid = companionManager?.getPairedUuid() - val pairedMac = companionManager?.getPairedMacAddress() - companionManager?.registerBackgroundScan(pairedMac, pairedUuid) - // 注意:这里只能检查绑定状态,无法直接判断连接状态 - // 实际连接状态需要通过广播接收器监听 - } + // 新增:仅在 API>=31 时检查 BLUETOOTH_CONNECT;Android 11 及以下跳过 + val needBtConnectPermission = android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S + if (needBtConnectPermission && + ContextCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_CONNECT) + != PackageManager.PERMISSION_GRANTED) { + Log.w(TAG, "缺少蓝牙连接权限(API>=31),无法检查已连接设备") + return + } + + val bondedDevices = adapter.bondedDevices + Log.i(TAG, "检查已绑定的设备数量: ${bondedDevices?.size ?: 0}") + + bondedDevices?.forEach { device -> + val deviceName = device.name ?: "Unknown" + Log.d(TAG, "已绑定设备: $deviceName (${device.address})") + + if (deviceName.equals(TARGET_DEVICE_NAME, ignoreCase = true)) { + Log.i(TAG, "发现已绑定的目标设备: $deviceName") + val pairedUuid = companionManager?.getPairedUuid() + val pairedMac = companionManager?.getPairedMacAddress() + companionManager?.registerBackgroundScan(pairedMac, pairedUuid) + // 注意:这里只能检查绑定状态,无法直接判断连接状态 + // 实际连接状态需要通过广播接收器监听 } - } else { - Log.w(TAG, "缺少蓝牙连接权限,无法检查已连接设备") } + } ?: run { + Log.e(TAG, "蓝牙适配器为空") } } catch (e: Exception) { Log.e(TAG, "检查已连接设备时发生异常", e) @@ -705,15 +711,12 @@ private var companionManager: BleCompanionManager? = null checkBluetoothHeadsetConnection { hasConnectedHeadset, headsetInfoList -> if (hasConnectedHeadset && headsetInfoList.isNotEmpty()) { Log.i(TAG, "检测到 ${headsetInfoList.size} 个蓝牙耳机已连接") - - // 查找匹配的配对设备 + val pairedMacAddress = BleService.getPairedMacAddress() val targetHeadset = headsetInfoList.find { it.address == pairedMacAddress } - + if (targetHeadset != null) { Log.i(TAG, "找到匹配的蓝牙耳机: ${targetHeadset.name} (${targetHeadset.address})") - - // 使用协程异步处理连接 launch { if (!BleService.isConnected()) { BleService.connect() @@ -743,55 +746,64 @@ private var companionManager: BleCompanionManager? = null private fun checkBluetoothHeadsetConnection(callback: (Boolean, List) -> Unit) { try { bluetoothAdapter?.let { adapter -> - if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_CONNECT) + // 仅在 API>=31 时检查 BLUETOOTH_CONNECT;Android 11 及以下跳过 + val needBtConnectPermission = android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S + if (needBtConnectPermission && + ContextCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { - Log.w(TAG, "缺少蓝牙连接权限,无法检查蓝牙耳机连接状态") + Log.w(TAG, "缺少蓝牙连接权限(API>=31),无法检查蓝牙耳机连接状态") callback(false, emptyList()) return } - // 检查HEADSET设备连接状态 - adapter.getProfileProxy(this, object : BluetoothProfile.ServiceListener { - override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) { - try { - val connectedDevices = proxy.connectedDevices - val hasConnectedHeadset = connectedDevices.isNotEmpty() - - Log.i(TAG, "蓝牙耳机连接设备数量: ${connectedDevices.size}") - - if (hasConnectedHeadset) { - // 返回所有连接的蓝牙耳机设备信息 - val headsetInfoList = connectedDevices.map { device -> - BluetoothHeadsetInfo( - name = device.name ?: "Unknown Headset", - address = device.address - ) - } + // 检查HEADSET设备连接状态(兼容捕获安全异常) + try { + adapter.getProfileProxy(this, object : BluetoothProfile.ServiceListener { + override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) { + try { + val connectedDevices = proxy.connectedDevices + val hasConnectedHeadset = connectedDevices.isNotEmpty() - Log.d(TAG, "蓝牙耳机连接设备列表:") - headsetInfoList.forEach { info -> - Log.d(TAG, " - ${info.name} (${info.address})") - } + Log.i(TAG, "蓝牙耳机连接设备数量: ${connectedDevices.size}") + if (hasConnectedHeadset) { + val headsetInfoList = connectedDevices.map { device -> + BluetoothHeadsetInfo( + name = device.name ?: "Unknown Headset", + address = device.address + ) + } + + Log.d(TAG, "蓝牙耳机连接设备列表:") + headsetInfoList.forEach { info -> + Log.d(TAG, " - ${info.name} (${info.address})") + } + + adapter.closeProfileProxy(BluetoothProfile.HEADSET, proxy) + callback(true, headsetInfoList) + } else { + adapter.closeProfileProxy(BluetoothProfile.HEADSET, proxy) + callback(false, emptyList()) + } + } catch (se: SecurityException) { + Log.e(TAG, "读取连接设备安全异常(厂商兼容)", se) adapter.closeProfileProxy(BluetoothProfile.HEADSET, proxy) - callback(true, headsetInfoList) - } else { + callback(false, emptyList()) + } catch (e: Exception) { + Log.e(TAG, "检查蓝牙耳机连接状态时发生异常", e) adapter.closeProfileProxy(BluetoothProfile.HEADSET, proxy) callback(false, emptyList()) } - - } catch (e: Exception) { - Log.e(TAG, "检查蓝牙耳机连接状态时发生异常", e) - adapter.closeProfileProxy(BluetoothProfile.HEADSET, proxy) - callback(false, emptyList()) } - } - - override fun onServiceDisconnected(profile: Int) { - Log.d(TAG, "蓝牙耳机服务断开连接") - } - }, BluetoothProfile.HEADSET) - + + override fun onServiceDisconnected(profile: Int) { + Log.d(TAG, "蓝牙耳机服务断开连接") + } + }, BluetoothProfile.HEADSET) + } catch (se: SecurityException) { + Log.e(TAG, "获取ProfileProxy安全异常(厂商兼容)", se) + callback(false, emptyList()) + } } ?: run { Log.e(TAG, "蓝牙适配器为空") callback(false, emptyList())