Browse Source

改成80字节上传

newdev_shunjiawei
fdp 1 year ago
parent
commit
261ef5e2b5
  1. 5
      lib/modules/login/bindings/login_binding.dart
  2. 35
      lib/modules/login/controllers/login_controller.dart
  3. 100
      local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt

5
lib/modules/login/bindings/login_binding.dart

@ -4,6 +4,7 @@ import '../controllers/login_controller.dart';
class LoginBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut<LoginController>(() => LoginController());
// 使用 put 而不是 lazyPut,确保控制器立即创建
Get.put<LoginController>(LoginController(), permanent: false);
}
}
}

35
lib/modules/login/controllers/login_controller.dart

@ -211,15 +211,30 @@ class LoginController extends GetxController {
String get displayContact => _displayContact.value;
List<String> get verificationCode => _verificationCode;
// 文本控制器
TextEditingController contactController = TextEditingController();
TextEditingController verificationCodeController = TextEditingController();
// 文本控制器 - 延迟初始化
TextEditingController? _contactController;
TextEditingController? _verificationCodeController;
// Getter 方法,确保控制器存在
TextEditingController get contactController {
_contactController ??= TextEditingController();
return _contactController!;
}
TextEditingController get verificationCodeController {
_verificationCodeController ??= TextEditingController();
return _verificationCodeController!;
}
@override
void onInit() {
super.onInit();
_viewState.value = LoginViewState.welcome;
// 初始化控制器
_contactController = TextEditingController();
_verificationCodeController = TextEditingController();
isChinaMainland.value =
Get.deviceLocale?.countryCode?.toUpperCase() == 'CN';
@ -236,17 +251,21 @@ class LoginController extends GetxController {
@override
void onClose() {
// Safely dispose controllers
// 安全地销毁控制器
try {
contactController.dispose();
_contactController?.dispose();
_contactController = null;
} catch (e) {
// Controller already disposed
Logger().e('销毁 contactController 失败: $e');
}
try {
verificationCodeController.dispose();
_verificationCodeController?.dispose();
_verificationCodeController = null;
} catch (e) {
// Controller already disposed
Logger().e('销毁 verificationCodeController 失败: $e');
}
super.onClose();
}

100
local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt

@ -126,14 +126,19 @@ object BleService {
private val isAudioSending = AtomicBoolean(false)
// 音频数据分块发送的常量
private val AUDIO_CHUNK_SIZE = 40 // 每次发送40字节
private val AUDIO_SEND_INTERVAL = 20L // 发送间隔10ms
private val AUDIO_CHUNK_SIZE = 80 // 每次发送80字节
private val AUDIO_SEND_INTERVAL = 40L // 发送间隔20ms
// 音频数据缓冲区,用于累积数据到80字节再发送
private val audioBuffer = mutableListOf<Byte>()
// 初始化状态
private var isInitialized = false
// 音频数据统计相关变量
private var bytesReceivedInCurrentSecond = 0
// 添加发送数据统计变量
private var bytesSentInCurrentSecond = 0
private var lastStatisticsTime = System.currentTimeMillis()
private val statisticsHandler = Handler(Looper.getMainLooper())
private val statisticsRunnable = object : Runnable {
@ -142,7 +147,9 @@ object BleService {
val timeDiff = currentTime - lastStatisticsTime
if (timeDiff >= 1000) { // 每秒统计一次
Log.i(TAG, "每秒接收音频数据: $bytesReceivedInCurrentSecond 字节")
Log.i(TAG, "每秒发送音频数据: $bytesSentInCurrentSecond 字节")
bytesReceivedInCurrentSecond = 0
bytesSentInCurrentSecond = 0
lastStatisticsTime = currentTime
}
statisticsHandler.postDelayed(this, 1000) // 每秒执行一次
@ -1376,28 +1383,33 @@ startBytesStatistics()
}
/**
* 将音频数据分块并加入发送队列
* 将音频数据添加到发送队列
* 只有当缓冲区达到80字节时才发送数据
* @param data 音频数据字节数组
*/
private fun addAudioDataToSendQueue(data: ByteArray) {
try {
// 将大数据分成40字节的小块
var offset = 0
while (offset < data.size) {
val chunkSize = minOf(AUDIO_CHUNK_SIZE, data.size - offset)
val chunk = ByteArray(chunkSize)
System.arraycopy(data, offset, chunk, 0, chunkSize)
// 将新数据添加到缓冲区
audioBuffer.addAll(data.toList())
// 当缓冲区达到80字节时,发送数据
while (audioBuffer.size >= 80) {
// 取出80字节数据
val chunk = ByteArray(80)
for (i in 0 until 80) {
chunk[i] = audioBuffer.removeAt(0)
}
// 将分块数据加入队列
// 将数据加入发送队列
if (!audioSendQueue.offer(chunk)) {
Log.w(TAG, "音频发送队列已满,丢弃数据块")
break
}
offset += chunkSize
}
Log.d(TAG, "音频数据已分块加入队列,原始大小: ${data.size} 字节,分块数: ${(data.size + AUDIO_CHUNK_SIZE - 1) / AUDIO_CHUNK_SIZE}")
// Log.d(TAG, "音频数据已加入缓冲区,当前缓冲区大小: ${audioBuffer.size} 字节")
} catch (e: Exception) {
Log.e(TAG, "分块音频数据异常: ${e.message}", e)
Log.e(TAG, "处理音频数据异常: ${e.message}", e)
}
}
@ -1448,11 +1460,13 @@ startBytesStatistics()
isAudioSending.set(false)
audioSendThread?.interrupt()
audioSendQueue.clear()
Log.i(TAG, "音频发送线程已停止,队列已清空")
audioBuffer.clear() // 清空音频缓冲区
Log.i(TAG, "音频发送线程已停止,队列和缓冲区已清空")
}
/**
* 发送单个音频数据块
* 发送音频数据块到设备
* @param chunk 要发送的音频数据块
*/
private fun sendAudioChunk(chunk: ByteArray) {
try {
@ -1468,9 +1482,61 @@ startBytesStatistics()
val isSuccess = bluetoothGatt?.writeCharacteristic(callWriteChar)
if (isSuccess == true) {
// 累加发送成功的字节数
bytesSentInCurrentSecond += chunk.size
Log.d(TAG, "成功发送音频数据块,大小: ${chunk.size} 字节")
} else {
Log.e(TAG, "发送音频数据块失败,大小: ${chunk.size} 字节")
// 详细的失败原因分析
val failureReason = StringBuilder("发送音频数据块失败,大小: ${chunk.size} 字节")
// 检查蓝牙连接状态
if (bluetoothGatt == null) {
failureReason.append(" - 原因: BluetoothGatt为空")
} else {
// 检查连接状态
val connectionState = bluetoothManager.getConnectionState(
bluetoothGatt!!.device,
BluetoothProfile.GATT
)
when (connectionState) {
BluetoothProfile.STATE_DISCONNECTED -> {
failureReason.append(" - 原因: 设备已断开连接")
}
BluetoothProfile.STATE_CONNECTING -> {
failureReason.append(" - 原因: 设备正在连接中")
}
BluetoothProfile.STATE_DISCONNECTING -> {
failureReason.append(" - 原因: 设备正在断开连接")
}
BluetoothProfile.STATE_CONNECTED -> {
// 连接正常,检查其他原因
if (callWriteChar == null) {
failureReason.append(" - 原因: 写入特征值为空")
} else {
// 检查特征值属性
val properties = callWriteChar!!.properties
if ((properties and BluetoothGattCharacteristic.PROPERTY_WRITE) == 0 &&
(properties and BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == 0) {
failureReason.append(" - 原因: 特征值不支持写入操作")
} else if (chunk.size > 512) { // BLE MTU通常限制
failureReason.append(" - 原因: 数据块过大 (${chunk.size} > 512字节)")
} else {
failureReason.append(" - 原因: 未知错误,可能是设备忙碌或缓冲区满")
}
}
}
else -> {
failureReason.append(" - 原因: 未知连接状态($connectionState)")
}
}
}
// 检查蓝牙适配器状态
if (bluetoothAdapter?.isEnabled != true) {
failureReason.append(" - 蓝牙适配器未启用")
}
Log.e(TAG, failureReason.toString())
}
} catch (e: Exception) {
Log.e(TAG, "发送音频数据块异常: ${e.message}", e)

Loading…
Cancel
Save