diff --git a/local_plugins/ble_service/android/libs/jl_audio_decode_V2.1.0_20013-release.aar b/local_plugins/ble_service/android/libs/jl_audio_decode_V2.1.0_20013-release.aar new file mode 100644 index 000000000..84091918b Binary files /dev/null and b/local_plugins/ble_service/android/libs/jl_audio_decode_V2.1.0_20013-release.aar differ 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 1fa24991d..a3550eeef 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 @@ -856,15 +856,15 @@ object BleService { //要先设置音频服务的通知,否则接收不到 // 设置音频服务的通知(如果存在) if (audioChar != null) { - setupNotifications(g, audioChar) - Log.i(TAG, "音频服务特征找到并设置通知") + setupNotifications(g, audioChar) + Log.i(TAG, "音频服务特征找到并设置通知") + } else { Log.w(TAG, "音频服务特征未找到") } - // 设置主服务的通知 - setupNotifications(g, notifyChar) - + setupNotifications(g, notifyChar) + // 在服务发现完成后,请求最大MTU requestMaxMtu(g) @@ -885,7 +885,7 @@ object BleService { } // 通知特征数据(命令和控制) BleConst.NOTIFY_CHAR_UUID -> { - // Log.i(TAG, "收到通知特征数据(命令和控制)") + Log.i(TAG, "收到通知特征数据(命令和控制)") // 判断数据类型 when { // 设备响应 (0xBB开头) @@ -955,17 +955,41 @@ object BleService { /** * 设置特征的通知功能 + * @param g BluetoothGatt实例 + * @param characteristic 要设置通知的特征 */ - private fun setupNotifications(g: BluetoothGatt, characteristic: BluetoothGattCharacteristic?) { + private fun setupNotifications(g: BluetoothGatt, characteristic: BluetoothGattCharacteristic?) : Boolean{ if (characteristic == null || characteristic.properties.and(BluetoothGattCharacteristic.PROPERTY_NOTIFY) == 0) { Log.w(TAG, "特征不支持通知功能: ${characteristic?.uuid}") - return + return false + } + + // 在本地启用特征通知监听 + val localResult = g.setCharacteristicNotification(characteristic, true) + if (!localResult) { + Log.e(TAG, "本地通知设置失败: ${characteristic.uuid}") + return false } + Log.d(TAG, "本地通知设置成功: ${characteristic.uuid}") - g.setCharacteristicNotification(characteristic, true) + // 获取客户端特征配置描述符 val desc = characteristic.getDescriptor(BleConst.CLIENT_CHAR_CONFIG_UUID) - desc?.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE - g.writeDescriptor(desc) + if (desc == null) { + Log.w(TAG, "未找到客户端配置描述符: ${characteristic.uuid}") + return false + } + + // 设置描述符值为启用通知 + desc.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE + + // 向远程设备写入描述符(异步操作,结果在onDescriptorWrite回调中处理) + val writeResult = g.writeDescriptor(desc) + if (writeResult) { + Log.d(TAG, "开始写入通知描述符: ${characteristic.uuid}") + } else { + Log.e(TAG, "通知描述符写入请求失败: ${characteristic.uuid}") + } + return true } /** diff --git a/local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/OpusAudioManager.kt b/local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/OpusAudioManager.kt index d3eb804b7..ccba13367 100644 --- a/local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/OpusAudioManager.kt +++ b/local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/OpusAudioManager.kt @@ -84,6 +84,9 @@ class OpusAudioManager { // Opus解码器实例 private var opusManager: OpusManager? = null private var option: OpusOption? = null + + private var opusManager1: OpusManager? = null + private var option1: OpusOption? = null private val mainHandler = Handler(Looper.getMainLooper()) // 解码音频数据队列和处理线程 @@ -124,6 +127,9 @@ class OpusAudioManager { opusManager = OpusManager() option = OpusOption() + opusManager1 = OpusManager() + option1 = OpusOption() + // 启动队列处理 startAudioQueueProcessing() @@ -174,6 +180,8 @@ class OpusAudioManager { // 清理Opus相关资源 opusManager = null option = null + opusManager1 = null + option1 = null callback = null isInitialized = false @@ -312,20 +320,27 @@ class OpusAudioManager { * @return 是否成功开始编码 */ fun startEncodeStream(): Boolean { - if (!isInitialized || opusManager == null) { + if (!isInitialized || opusManager1 == null) { Log.e(TAG, "OpusManager未初始化,无法开始编码") return false } // 如果已经在编码流,先停止 - if (opusManager?.isEncodeStream == true) { + if (opusManager1?.isEncodeStream == true) { Log.d(TAG, "Opus编码流已在运行") return true } - + + // 配置解码参数 + option1?.apply { + setHasHead(false) + setChannel(1) + setSampleRate(16000) + setPacketSize(40) + } try { Log.d(TAG, "准备开始Opus数据流编码") - opusManager?.startEncodeStream(object : OnEncodeStreamCallback { + opusManager1?.startEncodeStream(object : OnEncodeStreamCallback { override fun onEncodeStream(data: ByteArray?) { Log.d(TAG, "Opus编码回调收到数据,大小: ${data?.size ?: 0} bytes") if (data != null) { @@ -371,8 +386,8 @@ class OpusAudioManager { * @return 是否成功停止编码 */ fun stopEncodeStream(): Boolean { - if (opusManager?.isEncodeStream == true) { - opusManager?.stopEncodeStream() + if (opusManager1?.isEncodeStream == true) { + opusManager1?.stopEncodeStream() stopAudioSendThread() // 停止音频发送线程 Log.i(TAG, "已停止Opus数据流编码") callback?.onEncodeStreamStateChanged(false) @@ -389,16 +404,16 @@ class OpusAudioManager { * @param data 音频数据字节数组,通常为PCM格式 */ fun writeExternalAudioData(data: ByteArray) { - if (!isInitialized || opusManager == null) { + if (!isInitialized || opusManager1 == null) { Log.e(TAG, "OpusManager未初始化") return } // 如果已经在编码流中,直接写入数据 - if (opusManager?.isEncodeStream == true) { + if (opusManager1?.isEncodeStream == true) { Log.d(TAG, "正在进行Opus编码流,写入音频数据") // 将外部音频数据写入编码流 - opusManager?.writeEncodeStream(data) + opusManager1?.writeEncodeStream(data) } else { Log.w(TAG, "Opus编码流未启动,无法写入音频数据") } @@ -421,7 +436,7 @@ class OpusAudioManager { * @return 是否正在编码 */ fun isEncoding(): Boolean { - return opusManager?.isEncodeStream == true + return opusManager1?.isEncodeStream == true } /**