|
|
@ -126,11 +126,15 @@ object BleService { |
|
|
private val isAudioSending = AtomicBoolean(false) |
|
|
private val isAudioSending = AtomicBoolean(false) |
|
|
|
|
|
|
|
|
// 音频数据分块发送的常量 |
|
|
// 音频数据分块发送的常量 |
|
|
private val AUDIO_CHUNK_SIZE = 80 // 每次发送80字节 |
|
|
private val AUDIO_CHUNK_SIZE = 120 // 每次发送80字节 |
|
|
private val AUDIO_SEND_INTERVAL = 40L // 发送间隔20ms |
|
|
private val AUDIO_SEND_INTERVAL = 60L // 发送间隔20ms |
|
|
|
|
|
|
|
|
// 音频数据缓冲区,用于累积数据到80字节再发送 |
|
|
// 音频数据缓冲区,用于累积数据到80字节再发送 |
|
|
private val audioBuffer = mutableListOf<Byte>() |
|
|
private val audioBuffer = mutableListOf<Byte>() |
|
|
|
|
|
|
|
|
|
|
|
// 重发机制相关常量 |
|
|
|
|
|
private val MAX_RETRY_COUNT = 1 // 最大重试次数 |
|
|
|
|
|
private val RETRY_DELAY = 30L // 重试延迟时间(毫秒) |
|
|
|
|
|
|
|
|
// 初始化状态 |
|
|
// 初始化状态 |
|
|
private var isInitialized = false |
|
|
private var isInitialized = false |
|
|
@ -1393,10 +1397,10 @@ startBytesStatistics() |
|
|
audioBuffer.addAll(data.toList()) |
|
|
audioBuffer.addAll(data.toList()) |
|
|
|
|
|
|
|
|
// 当缓冲区达到80字节时,发送数据 |
|
|
// 当缓冲区达到80字节时,发送数据 |
|
|
while (audioBuffer.size >= 80) { |
|
|
while (audioBuffer.size >= AUDIO_CHUNK_SIZE) { |
|
|
// 取出80字节数据 |
|
|
// 取出80字节数据 |
|
|
val chunk = ByteArray(80) |
|
|
val chunk = ByteArray(AUDIO_CHUNK_SIZE) |
|
|
for (i in 0 until 80) { |
|
|
for (i in 0 until AUDIO_CHUNK_SIZE) { |
|
|
chunk[i] = audioBuffer.removeAt(0) |
|
|
chunk[i] = audioBuffer.removeAt(0) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -1465,10 +1469,11 @@ startBytesStatistics() |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 发送音频数据块到设备 |
|
|
* 发送音频数据块到设备(带重发机制) |
|
|
* @param chunk 要发送的音频数据块 |
|
|
* @param chunk 要发送的音频数据块 |
|
|
|
|
|
* @param retryCount 当前重试次数 |
|
|
*/ |
|
|
*/ |
|
|
private fun sendAudioChunk(chunk: ByteArray) { |
|
|
private fun sendAudioChunk(chunk: ByteArray, retryCount: Int = 0) { |
|
|
try { |
|
|
try { |
|
|
if (callWriteChar == null || bluetoothGatt == null) { |
|
|
if (callWriteChar == null || bluetoothGatt == null) { |
|
|
Log.e(TAG, "蓝牙连接或特征值未准备就绪") |
|
|
Log.e(TAG, "蓝牙连接或特征值未准备就绪") |
|
|
@ -1486,6 +1491,7 @@ startBytesStatistics() |
|
|
bytesSentInCurrentSecond += chunk.size |
|
|
bytesSentInCurrentSecond += chunk.size |
|
|
Log.d(TAG, "成功发送音频数据块,大小: ${chunk.size} 字节") |
|
|
Log.d(TAG, "成功发送音频数据块,大小: ${chunk.size} 字节") |
|
|
} else { |
|
|
} else { |
|
|
|
|
|
Log.e(TAG, "发送音频数据块失败,大小: ${chunk.size} 字节") |
|
|
// 详细的失败原因分析 |
|
|
// 详细的失败原因分析 |
|
|
val failureReason = StringBuilder("发送音频数据块失败,大小: ${chunk.size} 字节") |
|
|
val failureReason = StringBuilder("发送音频数据块失败,大小: ${chunk.size} 字节") |
|
|
|
|
|
|
|
|
@ -1537,9 +1543,44 @@ startBytesStatistics() |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Log.e(TAG, failureReason.toString()) |
|
|
Log.e(TAG, failureReason.toString()) |
|
|
|
|
|
|
|
|
|
|
|
// // 实现重发机制 |
|
|
|
|
|
// if (retryCount < MAX_RETRY_COUNT) { |
|
|
|
|
|
// Log.w(TAG, "准备重发音频数据块,重试次数: ${retryCount + 1}/$MAX_RETRY_COUNT") |
|
|
|
|
|
|
|
|
|
|
|
// // 延迟后重发 |
|
|
|
|
|
// audioSendHandler.postDelayed({ |
|
|
|
|
|
// val isSuccess = bluetoothGatt?.writeCharacteristic(callWriteChar) |
|
|
|
|
|
|
|
|
|
|
|
// if (isSuccess == true) { |
|
|
|
|
|
// Log.d(TAG, "重发音频数据块成功") |
|
|
|
|
|
// } else { |
|
|
|
|
|
// Log.e(TAG, "重发音频数据块失败") |
|
|
|
|
|
// } |
|
|
|
|
|
// }, RETRY_DELAY) |
|
|
|
|
|
// } else { |
|
|
|
|
|
// Log.e(TAG, "音频数据块发送失败,已达到最大重试次数($MAX_RETRY_COUNT),丢弃数据块") |
|
|
|
|
|
// // 可以选择将失败的数据块记录到日志或进行其他处理 |
|
|
|
|
|
// } |
|
|
} |
|
|
} |
|
|
} catch (e: Exception) { |
|
|
} catch (e: Exception) { |
|
|
Log.e(TAG, "发送音频数据块异常: ${e.message}", e) |
|
|
Log.e(TAG, "发送音频数据块异常: ${e.message}", e) |
|
|
|
|
|
|
|
|
|
|
|
// // 异常情况下也进行重发 |
|
|
|
|
|
// if (retryCount < MAX_RETRY_COUNT) { |
|
|
|
|
|
// Log.w(TAG, "发送异常,准备重发音频数据块,重试次数: ${retryCount + 1}/$MAX_RETRY_COUNT") |
|
|
|
|
|
// audioSendHandler.postDelayed({ |
|
|
|
|
|
// val isSuccess = bluetoothGatt?.writeCharacteristic(callWriteChar) |
|
|
|
|
|
|
|
|
|
|
|
// if (isSuccess == true) { |
|
|
|
|
|
// Log.d(TAG, "重发音频数据块成功") |
|
|
|
|
|
// } else { |
|
|
|
|
|
// Log.e(TAG, "重发音频数据块失败") |
|
|
|
|
|
// } |
|
|
|
|
|
// }, RETRY_DELAY) |
|
|
|
|
|
// } else { |
|
|
|
|
|
// Log.e(TAG, "音频数据块发送异常,已达到最大重试次数($MAX_RETRY_COUNT),丢弃数据块") |
|
|
|
|
|
// } |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} catch (e: Exception) { |
|
|
} catch (e: Exception) { |
|
|
|