diff --git a/local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt b/local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt index e25c554fb..ebad04d7e 100644 --- a/local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt +++ b/local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt @@ -140,6 +140,21 @@ object BleService { // 初始化状态 private var isInitialized = false + + /** + * 检查是否有蓝牙扫描权限 + */ + private fun hasBluetoothScanPermission(): Boolean { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + // Android 12+ 需要 BLUETOOTH_SCAN 权限 + context.checkSelfPermission(Manifest.permission.BLUETOOTH_SCAN) == + android.content.pm.PackageManager.PERMISSION_GRANTED + } else { + // Android 12 以下使用 ACCESS_FINE_LOCATION 权限 + context.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == + android.content.pm.PackageManager.PERMISSION_GRANTED + } + } // 音频数据统计相关变量 private var bytesReceivedInCurrentSecond = 0 @@ -280,18 +295,22 @@ object BleService { /** * 开始主动扫描BLE设备 + * @param uuids 要扫描的服务UUID列表 * @param timeout 扫描超时时间(毫秒) * @return 是否成功开始扫描 */ fun startScan(uuids: List, timeout: Long = 15000): Boolean { -// Log.i(TAG, "liwei---------startScan 1 $deviceName") if (!isInitialized) { Log.e(TAG, "BLE服务未初始化") return false } -// Log.i(TAG, "liwei---------startScan 2") - // 获取一个局部引用,避免并发访问问题 -// val scanner = bluetoothLeScanner ?: return false + + // 检查蓝牙扫描权限 + if (!hasBluetoothScanPermission()) { + Log.e(TAG, "开始扫描失败: 缺少 BLUETOOTH_SCAN 权限") + return false + } + // 💡 每次都重新取最新实例 val scanner = bluetoothLeScanner ?: run { Log.e(TAG, "bluetoothLeScanner == null,尝试重启蓝牙") @@ -299,58 +318,65 @@ object BleService { return false } -// Log.i(TAG, "liwei---------startScan 3") if (isScanning) return false -// Log.i(TAG, "liwei---------startScan 4") + Log.i(TAG, "开始主动扫描BLE设备...") scanResults.clear() -// Log.i(TAG, "liwei---------startScan 5") - val filter = ScanFilter.Builder() - // .setServiceUuid(ParcelUuid(BleConst.PRIMARY_SERVICE_UUID)) -// .setServiceUuid(ParcelUuid(java.util.UUID.fromString("00000201-0000-1000-8000-00805f9b34fb"))) - .build() -// val filters = uuids.mapNotNull { uuidStr -> -// try { -// // 清理UUID字符串,移除非十六进制字符 -// val cleanUuidStr = uuidStr.replace("[^0-9A-Fa-f]".toRegex(), "") -// -// // 验证清理后的字符串长度(应该是4位十六进制字符) -// if (cleanUuidStr.length != 4) { -// Log.w(TAG, "无效的UUID格式: $uuidStr,清理后: $cleanUuidStr,长度: ${cleanUuidStr.length}") -// return@mapNotNull null -// } -// -// val fullUuid = "0000$cleanUuidStr-0000-1000-8000-00805f9b34fb" -// Log.d(TAG, "扫描uuid: $fullUuid") -// -// ScanFilter.Builder() -// .setServiceUuid(ParcelUuid(UUID.fromString(fullUuid))) -// .build() -// } catch (e: IllegalArgumentException) { -// Log.e(TAG, "构造UUID失败: $uuidStr", e) -// null -// } -// } + + // 构建扫描过滤器 - 参考 registerBackgroundScan 的实现 + val filters = mutableListOf() + + // 如果提供了额外的UUID,也添加到过滤器中 + uuids.forEach { uuidStr -> + try { + val uuid = when { + uuidStr.length == 4 -> { + // 短UUID,转换为完整UUID + val fullUuid = "0000$uuidStr-0000-1000-8000-00805f9b34fb" + UUID.fromString(fullUuid) + } + uuidStr.length == 36 -> { + // 完整UUID + UUID.fromString(uuidStr) + } + else -> { + Log.w(TAG, "无效的UUID格式: $uuidStr") + return@forEach + } + } + + val filter = ScanFilter.Builder() + //.setServiceUuid(ParcelUuid(uuid)) + .build() + filters.add(filter) + Log.d(TAG, "添加扫描过滤器UUID: $uuid") + } catch (e: IllegalArgumentException) { + Log.e(TAG, "构造UUID失败: $uuidStr", e) + } + } + + // 扫描设置 - 参考 registerBackgroundScan 的配置 val settings = ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_LOW_POWER) - .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES) // 推荐:不会触发权限问题 + .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES) .setReportDelay(0) .build() -// Log.i(TAG, "liwei---------startScan 7") + try { - scanner.startScan(listOf(filter), settings, scanCallback) + // 使用过滤器列表进行扫描 + scanner.startScan(filters, settings, scanCallback) isScanning = true -// Log.i(TAG, "liwei---------startScan 8") + // 设置扫描超时 scanHandler.postDelayed({ Log.d(TAG, "扫描超时,停止扫描") stopScan() }, timeout) -// Log.i(TAG, "liwei---------startScan 9") + + Log.i(TAG, "已启动BLE扫描,过滤器数量: ${filters.size}") return true } catch (e: Exception) { Log.e(TAG, "启动扫描失败: ${e.message}", e) -// Log.i(TAG, "liwei---------startScan 10") isScanning = false return false }