Browse Source

Merge branch 'new_dev' of https://github.com/deepcloud2048/deep_voice into new_dev

newdev_shunjiawei
liwei1dao 1 year ago
parent
commit
bb64046e02
  1. 122
      lib/data/services/ble_manager.dart
  2. 123
      lib/modules/home/controllers/home_controller.dart
  3. 4
      lib/modules/home/views/home_view.dart
  4. 11
      lib/modules/pairing/controllers/pairing_controller.dart
  5. 512
      lib/modules/translation/controllers/translation_controller.dart
  6. 73
      lib/modules/translation/views/translation_view.dart
  7. 2
      local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/BleAgent.kt
  8. 2
      local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift
  9. 4
      local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureSpeechPlugin.kt
  10. 2
      local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureSpeechPlugin.swift
  11. 2
      local_plugins/azure_speech/ios/azure_speech/Sources/tools/MicrophoneCapture.swift
  12. 4
      local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt
  13. 2
      local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleServicePlugin.kt
  14. 6
      local_plugins/ble_service/ios/ble_service/Sources/ble_service/BleService.swift
  15. 2
      local_plugins/ble_service/ios/ble_service/Sources/ble_service/SwiftBleServicePlugin.swift
  16. 4
      local_plugins/ble_service/ios/ble_service/Sources/ble_service/SwiftOpusAudioProcessor.swift
  17. 2
      local_plugins/ota/android/src/main/kotlin/com/example/ota/OtaPlugin.kt
  18. 2
      pubspec.yaml

122
lib/data/services/ble_manager.dart

@ -156,16 +156,21 @@ class BleManager extends GetxService {
/// 设置BLE事件监听
void _setupBleListener() {
Logger.info('lxm--_setupBleListener被调用,开始设置BLE事件监听');
_statusSubscription?.cancel();
_dataSubscription?.cancel();
try {
Logger.info('lxm--开始监听BLE状态更新流');
// 监听BLE状态更新
_statusSubscription = _bleService.onStatusUpdated.listen(
(event) {
Logger.info('lxm--收到BLE状态更新事件: $event');
if (event is Map) {
Logger.info('lxm--事件是Map类型,开始处理');
// 处理连接状态更新
if (event['type'] == 'connectionStateChanged') {
Logger.info('lxm--处理连接状态变化事件');
final state = event['state'] as int;
final oldState = _connectionState.value;
_connectionState.value = state;
@ -175,21 +180,23 @@ class BleManager extends GetxService {
// 连接状态转换
if (state == BleConnectionState.connected) {
Logger.info('BLE设备已连接');
Logger.info('lxm--BLE设备已连接');
_isConnected.value = true;
// 在连接成功后延迟 300 毫秒获取设备信息(可根据需要调整时间)
Future.delayed(const Duration(milliseconds: 300), () {
// 可选:检查是否仍处于连接状态
if (_isConnected.value) {
Logger.info('lxm--连接后延迟获取设备信息(当前被注释)');
// fetchDeviceInfo();
}
});
} else if (state == BleConnectionState.disconnected ||
state == BleConnectionState.error) {
Logger.info('BLE设备已断开或发生错误');
Logger.info('lxm--BLE设备已断开或发生错误');
_isConnected.value = false;
// 更新设备信息Add commentMore actions
Logger.info('lxm--断开连接时重置设备信息为0');
_updateDeviceInfoIfNeeded(
batteryLevel: 0,
leftEarBattery: 0,
@ -207,71 +214,99 @@ class BleManager extends GetxService {
}
}
Logger.info('lxm--准备调用_processDeviceInfo处理设备信息');
// 处理设备信息
_processDeviceInfo(event);
} else {
Logger.info('lxm--事件不是Map类型: ${event.runtimeType}');
}
},
onError: (error) {
Logger.error('BLE状态事件流错误: $error');
Logger.error('lxm--BLE状态事件流错误: $error');
},
);
Logger.info('lxm--BLE状态监听器设置完成');
// 监听BLE数据流
} catch (e) {
Logger.error('设置BLE事件监听器失败: ${e.toString()}');
Logger.error('lxm--设置BLE事件监听器失败: ${e.toString()}');
}
}
/// 处理来自原生层的设备信息
void _processDeviceInfo(Map<dynamic, dynamic> event) {
try {
Logger.info('lxm--_processDeviceInfo被调用');
Logger.info('lxm--接收到的事件数据: $event');
// 检查是否是设备信息响应
if (event.containsKey('command') && event.containsKey('success')) {
Logger.info('lxm--事件包含command和success字段');
final bool success = event['success'] as bool;
Logger.info('lxm--命令执行成功状态: $success');
if (!success) {
Logger.warning('设备命令执行失败: ${event['command']}');
Logger.warning('lxm--设备命令执行失败: ${event['command']}');
return;
}
// 根据命令类型处理不同信息
final command = event['command'];
Logger.info('lxm--命令类型: $command (${command.runtimeType})');
if (command is int) {
Logger.info('lxm--基于命令ID处理: $command');
// 基于命令ID处理
_processDeviceInfoByCommandId(command, event);
} else if (command is String) {
Logger.info('lxm--基于命令名称处理: $command');
// 基于命令名称处理
_processDeviceInfoByCommandName(command, event);
} else {
Logger.warning('lxm--未知的命令类型: ${command.runtimeType}');
}
} else {
Logger.info('lxm--事件不包含command或success字段,跳过处理');
Logger.info('lxm--事件包含的键: ${event.keys.toList()}');
}
} catch (e) {
Logger.error('处理设备信息异常: ${e.toString()}');
Logger.error('lxm--处理设备信息异常: ${e.toString()}');
Logger.error('lxm--异常堆栈: ${StackTrace.current}');
}
}
/// 根据命令ID处理设备信息
void _processDeviceInfoByCommandId(
int commandId, Map<dynamic, dynamic> data) {
Logger.info('lxm--_processDeviceInfoByCommandId被调用,命令ID: $commandId');
Logger.info('lxm--命令数据: $data');
switch (commandId) {
case BleCommands.GET_VERSION:
Logger.info('lxm--处理版本信息命令');
_updateVersionInfoFromData(data);
break;
case BleCommands.GET_PRODUCT_ID:
Logger.info('lxm--处理产品ID命令');
_updateProductIdFromData(data);
break;
case BleCommands.GET_PRODUCT_COLOR:
Logger.info('lxm--处理产品颜色命令(暂未实现)');
break;
case BleCommands.GET_BATTERY_INFO:
Logger.info('lxm--处理电池信息命令,准备调用_updateBatteryInfoFromData');
_updateBatteryInfoFromData(data);
Logger.info('lxm--电池信息处理完成');
break;
case BleCommands.CONTROL_CODEC:
Logger.info('lxm--处理编解码控制命令');
// 处理通话状态
print(" CONTROL_CODEC: $commandId,$data");
//_isCall.value = data['callStatus'] as bool? ?? false;
break;
default:
Logger.warning('lxm--未处理的命令ID: $commandId,数据: $data');
print(" 未处理的命令ID: $commandId,$data");
Logger.info('未处理的命令ID: $commandId');
}
}
@ -302,14 +337,34 @@ class BleManager extends GetxService {
/// 更新电池信息
void _updateBatteryInfoFromData(Map<dynamic, dynamic> data) {
try {
Logger.info('lxm--_updateBatteryInfoFromData被调用');
Logger.info('lxm--接收到的原始数据: $data');
// 确保数据中包含电池信息
if (!data.containsKey('leftEarBattery') ||
!data.containsKey('rightEarBattery') ||
!data.containsKey('caseBattery')) {
Logger.warning('电池信息数据不完整');
Logger.warning('lxm--电池信息数据不完整,缺少必要字段');
Logger.warning('lxm--数据包含的键: ${data.keys.toList()}');
return;
}
Logger.info('lxm--原始电池数据解析:');
Logger.info(
'lxm-- leftEarBattery原始值: ${data['leftEarBattery']} (类型: ${data['leftEarBattery'].runtimeType})');
Logger.info(
'lxm-- rightEarBattery原始值: ${data['rightEarBattery']} (类型: ${data['rightEarBattery'].runtimeType})');
Logger.info(
'lxm-- caseBattery原始值: ${data['caseBattery']} (类型: ${data['caseBattery'].runtimeType})');
Logger.info(
'lxm-- leftEarCharging原始值: ${data['leftEarCharging']} (类型: ${data['leftEarCharging'].runtimeType})');
Logger.info(
'lxm-- rightEarCharging原始值: ${data['rightEarCharging']} (类型: ${data['rightEarCharging'].runtimeType})');
Logger.info(
'lxm-- caseCharging原始值: ${data['caseCharging']} (类型: ${data['caseCharging'].runtimeType})');
Logger.info(
'lxm-- batteryLevel原始值: ${data['batteryLevel']} (类型: ${data['batteryLevel']?.runtimeType})');
// 提取电池信息
final int leftBattery = (data['leftEarBattery'] as int? ?? 0) > 100
? 0
@ -329,6 +384,16 @@ class BleManager extends GetxService {
// 获取整体电量(原生层使用左耳电量作为主要指示)
final int overallBattery = data['batteryLevel'] as int? ?? leftBattery;
Logger.info('lxm--处理后的电池数据:');
Logger.info('lxm-- leftBattery: $leftBattery');
Logger.info('lxm-- rightBattery: $rightBattery');
Logger.info('lxm-- caseBattery: $caseBattery');
Logger.info('lxm-- leftCharging: $leftCharging');
Logger.info('lxm-- rightCharging: $rightCharging');
Logger.info('lxm-- caseCharging: $caseCharging');
Logger.info('lxm-- overallBattery: $overallBattery');
Logger.info('lxm--准备调用_updateDeviceInfoIfNeeded');
// 更新设备信息
_updateDeviceInfoIfNeeded(
batteryLevel: overallBattery,
@ -341,9 +406,10 @@ class BleManager extends GetxService {
);
Logger.info(
'设备电池信息已更新: 电量=$overallBattery%, 左耳=$leftBattery%, 右耳=$rightBattery%, 充电仓=$caseBattery%');
'lxm--设备电池信息已更新: 电量=$overallBattery%, 左耳=$leftBattery%, 右耳=$rightBattery%, 充电仓=$caseBattery%');
} catch (e) {
Logger.error('更新电池信息失败: ${e.toString()}');
Logger.error('lxm--更新电池信息失败: ${e.toString()}');
Logger.error('lxm--错误堆栈: ${StackTrace.current}');
}
}
@ -406,8 +472,18 @@ class BleManager extends GetxService {
String? firmwareProductId,
String? firmwareProductColor,
}) {
Logger.info('lxm--_updateDeviceInfoIfNeeded被调用');
Logger.info(
'lxm--传入参数: batteryLevel=$batteryLevel, leftEarBattery=$leftEarBattery, rightEarBattery=$rightEarBattery, caseBattery=$caseBattery');
Logger.info(
'lxm--充电状态: leftEarCharging=$leftEarCharging, rightEarCharging=$rightEarCharging, caseCharging=$caseCharging');
Logger.info('lxm--当前deviceInfo.value是否为null: ${deviceInfo.value == null}');
// 如果设备信息已存在,则更新
if (deviceInfo.value != null) {
Logger.info('lxm--设备信息已存在,进行更新操作');
Logger.info('lxm--更新前的设备信息: ${deviceInfo.value}');
deviceInfo.value = deviceInfo.value!.copyWith(
batteryLevel: batteryLevel ?? deviceInfo.value?.batteryLevel,
leftEarBattery: leftEarBattery ?? deviceInfo.value?.leftEarBattery,
@ -423,17 +499,20 @@ class BleManager extends GetxService {
firmwareProductColor:
firmwareProductColor ?? deviceInfo.value!.firmwareProductColor,
);
Logger.info('lxm--更新后的设备信息: ${deviceInfo.value}');
}
// 创建设备信息
// 如果设备信息不存在,但有地址和名称,则创建新的设备信息
else if (deviceInfo.value == null &&
_isConnected.value &&
(firmwareVersion != null || batteryLevel != null)) {
Logger.info('lxm--设备信息不存在,创建新的设备信息对象');
// 使用保存的设备信息创建新的DeviceInfo对象
String deviceAddress = _currentDeviceAddress ?? "";
String deviceName = _currentDeviceName ?? "";
Logger.info('创建新的设备信息对象: address=$deviceAddress, name=$deviceName');
Logger.info('lxm--创建新的设备信息对象: address=$deviceAddress, name=$deviceName');
deviceInfo.value = DeviceInfo(
address: deviceAddress,
name: deviceName,
@ -448,6 +527,11 @@ class BleManager extends GetxService {
firmwareProductId: firmwareProductId ?? '',
firmwareProductColor: firmwareProductColor ?? '',
);
Logger.info('lxm--新创建的设备信息: ${deviceInfo.value}');
} else {
Logger.info(
'lxm--不满足更新条件: deviceInfo.value == null: ${deviceInfo.value == null}, _isConnected.value: ${_isConnected.value}, firmwareVersion: $firmwareVersion, batteryLevel: $batteryLevel');
}
}
@ -639,21 +723,28 @@ class BleManager extends GetxService {
}
}
Logger.info('lxm--准备调用AgentService.startAgentService启动BLE服务');
final result = await AgentService.startAgentService(config);
Logger.info('lxm--AgentService.startAgentService调用结果: $result');
if (result) {
Logger.info('BLE服务启动成功');
Logger.info('lxm--BLE服务启动成功');
// 添加延迟以等待设备连接
Logger.info('lxm--等待2秒让设备连接');
await Future.delayed(const Duration(seconds: 2));
// 检查连接状态
Logger.info('lxm--检查设备连接状态');
final isConnected = await _bleService.isConnected();
Logger.info('lxm--设备连接状态检查结果: $isConnected');
if (isConnected) {
Logger.info('lxm--设备已连接,更新连接状态');
_isConnected.value = true;
_connectionState.value = BleConnectionState.connected;
// 如果设备信息存在,则获取详细信息
Logger.info('lxm--准备获取设备详细信息');
if (deviceInfo.value != null) {
// 获取详细设备信息
// fetchDeviceInfo();
@ -705,9 +796,12 @@ class BleManager extends GetxService {
/// 主动获取电池信息
Future<bool> fetchBatteryInfo() async {
try {
return await _bleService.getBatteryInfo();
Logger.info('lxm--fetchBatteryInfo被调用,准备向设备发送获取电池信息指令');
final result = await _bleService.getBatteryInfo();
Logger.info('lxm--getBatteryInfo指令发送结果: $result');
return result;
} catch (e) {
Logger.error('获取电池信息失败: ${e.toString()}');
Logger.error('lxm--获取电池信息失败: ${e.toString()}');
return false;
}
}

123
lib/modules/home/controllers/home_controller.dart

@ -1,5 +1,5 @@
import 'package:get/get.dart';
import 'dart:async';
// 移除了dart:async导入,因为不再使用Timer
import '../../../data/services/novice_guide_service.dart';
import '../../../routes/app_routes.dart';
import '../../../core/utils/logger.dart';
@ -24,10 +24,7 @@ class HomeController extends GetxController {
final _isFullyConnected = false.obs;
String? _lastConnectedDeviceName;
// 添加电池信息定时刷新相关变量
Timer? _batteryRefreshTimer;
static const Duration _batteryRefreshInterval =
Duration(seconds: 2); // 2秒刷新一次
// 移除了电池信息定时刷新相关变量
// OTA检查服务
late final OtaCheckService _otaCheckService;
@ -37,21 +34,51 @@ class HomeController extends GetxController {
BluetoothDevice? get currentDevice => _bluetoothManager.currentDevice;
Rx<DeviceInfo?> get deviceInfo => _bleManager.deviceInfo;
final leftEarBattery = 0.obs;
final rightEarBattery = 0.obs;
static final leftEarBattery = 0.obs;
static final rightEarBattery = 0.obs;
final caseBattery = 0.obs;
final leftEarCharging = false.obs;
final rightEarCharging = false.obs;
final caseCharging = false.obs;
final firmwareVersion = ''.obs;
void updateDeviceInfo(DeviceInfo? newDeviceInfo) {
leftEarBattery.value = newDeviceInfo?.leftEarBattery ?? 0;
rightEarBattery.value = newDeviceInfo?.rightEarBattery ?? 0;
Logger.d(_tag, 'lxm--updateDeviceInfo被调用');
Logger.d(_tag, 'lxm--接收到的DeviceInfo: $newDeviceInfo');
if (newDeviceInfo != null) {
Logger.d(_tag, 'lxm--原始数据 - 左耳电量: ${newDeviceInfo.leftEarBattery}');
Logger.d(_tag, 'lxm--原始数据 - 右耳电量: ${newDeviceInfo.rightEarBattery}');
Logger.d(_tag, 'lxm--原始数据 - 充电仓电量: ${newDeviceInfo.caseBattery}');
Logger.d(_tag, 'lxm--原始数据 - 左耳充电: ${newDeviceInfo.leftEarCharging}');
Logger.d(_tag, 'lxm--原始数据 - 右耳充电: ${newDeviceInfo.rightEarCharging}');
Logger.d(_tag, 'lxm--原始数据 - 充电仓充电: ${newDeviceInfo.caseCharging}');
Logger.d(_tag, 'lxm--原始数据 - 固件版本: ${newDeviceInfo.firmwareVersion}');
} else {
Logger.d(_tag, 'lxm--接收到的DeviceInfo为null');
}
// 只有当新数据不为0时才更新电池值,否则保持原值
if ((newDeviceInfo?.leftEarBattery ?? 0) != 0) {
Logger.d(_tag, 'lxm--更新左耳电量: ${newDeviceInfo!.leftEarBattery}');
leftEarBattery.value = newDeviceInfo.leftEarBattery;
}
if ((newDeviceInfo?.rightEarBattery ?? 0) != 0) {
Logger.d(_tag, 'lxm--更新右耳电量: ${newDeviceInfo!.rightEarBattery}');
rightEarBattery.value = newDeviceInfo.rightEarBattery;
}
caseBattery.value = newDeviceInfo?.caseBattery ?? 0;
leftEarCharging.value = newDeviceInfo?.leftEarCharging ?? false;
rightEarCharging.value = newDeviceInfo?.rightEarCharging ?? false;
caseCharging.value = newDeviceInfo?.caseCharging ?? false;
firmwareVersion.value = newDeviceInfo?.firmwareVersion ?? '';
Logger.d(_tag, 'lxm--更新后的值 - 左耳电量: ${leftEarBattery.value}');
Logger.d(_tag, 'lxm--更新后的值 - 右耳电量: ${rightEarBattery.value}');
Logger.d(_tag, 'lxm--更新后的值 - 充电仓电量: ${caseBattery.value}');
Logger.d(_tag, 'lxm--更新后的值 - 左耳充电: ${leftEarCharging.value}');
Logger.d(_tag, 'lxm--更新后的值 - 右耳充电: ${rightEarCharging.value}');
Logger.d(_tag, 'lxm--更新后的值 - 充电仓充电: ${caseCharging.value}');
Logger.d(_tag, 'lxm--更新后的值 - 固件版本: ${firmwareVersion.value}');
}
Worker? _deviceInfoWorker;
@ -68,7 +95,7 @@ class HomeController extends GetxController {
super.onInit();
_otaCheckService = Get.find<OtaCheckService>();
_initWithCachedInfo();
// _startBatteryRefreshTimer(); // 启动电池信息定时刷新
// 移除了电池信息定时刷新的启动
}
@override
@ -76,7 +103,7 @@ class HomeController extends GetxController {
_deviceInfoWorker?.dispose();
_classicBluetoothWorker?.dispose();
_bleConnectionWorker?.dispose();
_stopBatteryRefreshTimer(); // 停止定时器
// 移除了定时器停止逻辑
super.onClose();
}
@ -87,8 +114,13 @@ class HomeController extends GetxController {
void _setupStateListeners() {
_deviceInfoWorker = ever(_bleManager.deviceInfo, (DeviceInfo? info) {
Logger.d(_tag, 'lxm--_deviceInfoWorker监听器被触发');
Logger.d(_tag, 'lxm--从BleManager接收到的DeviceInfo: $info');
if (info != null) {
Logger.d(_tag, 'lxm--DeviceInfo不为null,调用updateDeviceInfo');
updateDeviceInfo(info);
} else {
Logger.d(_tag, 'lxm--DeviceInfo为null,跳过更新');
}
update();
});
@ -108,10 +140,7 @@ class HomeController extends GetxController {
Future<void> refreshDeviceConnection() async {
await _checkConnectionStatus();
// 如果设备已连接,立即刷新电池信息
if (_isFullyConnected.value) {
await _refreshBatteryInfo();
}
// 移除了立即刷新电池信息的逻辑
}
void rescanDevices() {
@ -149,24 +178,15 @@ class HomeController extends GetxController {
Future.delayed(const Duration(seconds: 1), () async {
await _bleManager.fetchDeviceInfo();
});
// 连接成功后立即刷新一次电池信息
Future.delayed(const Duration(milliseconds: 500), () {
_refreshBatteryInfo();
});
// 移除了连接成功后的电池信息刷新
// 连接成功后检查OTA升级
Future.delayed(const Duration(seconds: 2), () {
_checkOtaUpgrade();
});
}
// 根据连接状态控制定时器
// if (isNowConnected) {
// _startBatteryRefreshTimer(); // 连接时启动定时器
// } else {
// _stopBatteryRefreshTimer(); // 断开时停止定时器
// // 注意:不再重置OTA检查状态,因为现在由全局服务管理
// }
// 移除了根据连接状态控制定时器的逻辑
}
update();
@ -175,7 +195,7 @@ class HomeController extends GetxController {
if (_isFullyConnected.value) {
_isFullyConnected.value = false;
_isFullyConnected.refresh();
_stopBatteryRefreshTimer(); // 发生错误时停止定时器
// 移除了发生错误时停止定时器的逻辑
// 注意:不再重置OTA检查状态,因为现在由全局服务管理
update();
}
@ -299,50 +319,7 @@ class HomeController extends GetxController {
: 'unknown'.tr;
}
/// 启动电池信息定时刷新
void _startBatteryRefreshTimer() {
_stopBatteryRefreshTimer(); // 先停止现有定时器
_batteryRefreshTimer = Timer.periodic(_batteryRefreshInterval, (timer) {
// 只有在设备完全连接时才刷新电池信息
if (_isFullyConnected.value) {
_refreshBatteryInfo();
}
});
Logger.d(_tag, '电池信息定时刷新已启动,间隔: ${_batteryRefreshInterval.inSeconds}秒');
}
/// 停止电池信息定时刷新
void _stopBatteryRefreshTimer() {
if (_batteryRefreshTimer != null) {
_batteryRefreshTimer!.cancel();
_batteryRefreshTimer = null;
Logger.d(_tag, '电池信息定时刷新已停止');
}
}
/// 刷新电池信息
Future<void> _refreshBatteryInfo() async {
try {
if (!_isFullyConnected.value) {
return;
}
//Logger.d(_tag, '开始刷新电池信息...');
// 通过BLE管理器获取最新的电池信息
final success = await _bleManager.fetchBatteryInfo();
if (success) {
//Logger.d(_tag, '电池信息刷新请求发送成功');
} else {
//Logger.w(_tag, '电池信息刷新请求发送失败');
}
} catch (e) {
//Logger.e(_tag, '刷新电池信息时发生错误: $e');
}
}
// 移除了电池信息定时刷新相关方法
/// 检查OTA固件升级
/// 在BLE连接成功后调用,检查是否需要升级

4
lib/modules/home/views/home_view.dart

@ -450,8 +450,8 @@ class HomeView extends GetView<HomeController> {
Widget _buildBatteryInfoGrid(bool isDarkMode) {
return Obx(() {
// 获取各部分电池电量
final leftBattery = controller.leftEarBattery;
final rightBattery = controller.rightEarBattery;
final leftBattery = HomeController.leftEarBattery;
final rightBattery = HomeController.rightEarBattery;
final caseBattery = controller.caseBattery;
// 获取充电状态
final leftEarCharging = controller.leftEarCharging;

11
lib/modules/pairing/controllers/pairing_controller.dart

@ -8,6 +8,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'dart:async';
import 'package:permission_handler/permission_handler.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../../routes/app_routes.dart';
import '../../../core/utils/logger.dart';
import 'dart:io';
@ -1131,8 +1132,14 @@ class PairingController extends GetxController with WidgetsBindingObserver {
/// 打开蓝牙设置 - 简化版本
void _openBluetoothSettings() async {
if (Platform.isIOS) {
// iOS平台:直接显示用户指导对话框
_showBluetoothGuideDialog();
const url = 'App-Prefs:';
//拉起iOS系统设置app到前台,使用旧接口生效
if (await canLaunch(url)) {
await launch(url);
} else {
// 如果无法直接打开,回退到显示指导对话框
_showBluetoothGuideDialog();
}
} else {
// Android平台使用原有方式
AppSettings.openAppSettings(type: AppSettingsType.bluetooth);

512
lib/modules/translation/controllers/translation_controller.dart

File diff suppressed because it is too large

73
lib/modules/translation/views/translation_view.dart

@ -1,4 +1,3 @@
import 'dart:async';
import 'dart:ui';
import 'dart:io';
@ -538,57 +537,6 @@ class TranslationView extends GetView<TranslationController> {
);
}
// // 按住说话按钮组件
// Widget _buildHoldToTalkButton({
// required bool isDarkMode,
// required int speakerId,
// required int activeSpeaker,
// required IconData icon,
// required String label,
// }) {
// bool isActive = activeSpeaker == speakerId;
// return Listener(
// onPointerDown: (_) {
// if (activeSpeaker == 0) {
// // 没有激活的按钮时才能激活
// if (speakerId == 1) {
// //耳机收音
// controller.restoreOriginalAudioState();
// //controller.setActiveSpeaker(speakerId);
// } else {
// controller.disableBluetoothAudio();
// }
// controller.setActiveSpeaker(speakerId);
// //controller.startRecognition();
// }
// },
// onPointerUp: (_) {
// if (isActive) {
// //controller.stopRecognition();
// controller.setActiveSpeaker(0);
// }
// },
// child: Container(
// width: 60.w,
// height: 60.w,
// decoration: BoxDecoration(
// color: isActive
// ? (isDarkMode ? Colors.green[700] : Colors.green) // 激活状态颜色
// : (isDarkMode ? AppColors.primary : Colors.blue),
// shape: BoxShape.circle,
// ),
// child: Icon(
// Icons.mic, // 麦克风图标
// color: isActive ? Colors.white : Colors.white.withOpacity(0.7),
// size: 30.sp,
// ),
// ),
// );
// }
// 按住说话按钮组件
Widget _buildHoldToTalkButton({
required bool isDarkMode,
@ -599,22 +547,25 @@ class TranslationView extends GetView<TranslationController> {
}) {
bool isActive = activeSpeaker == speakerId;
bool isDisabled = activeSpeaker != 0 && activeSpeaker != speakerId;
Timer? _holdTimer; // 增加延迟触发的计时器
return Listener(
onPointerDown: (_) async {
// 同步检查权限状态,不使用 await
// 检查权限
if (!controller.hasRecordPermission.value) {
Get.snackbar('权限提示', '需要麦克风权限才能使用录音功能');
return;
}
controller.setActiveSpeaker(speakerId);
},
onPointerUp: (_) {
controller.setActiveSpeaker(0);
// 只有在没有其他按钮激活时才能激活当前按钮
if (activeSpeaker == 0) {
await controller.setActiveSpeaker(speakerId);
}
},
onPointerCancel: (_) {
controller.setActiveSpeaker(0);
onPointerUp: (_) async {
// 松开按钮时,如果当前按钮是激活状态,则停止
if (isActive) {
await controller.setActiveSpeaker(0);
}
},
child: AnimatedContainer(
duration: const Duration(milliseconds: 200),
@ -643,7 +594,7 @@ class TranslationView extends GetView<TranslationController> {
Stack(
alignment: Alignment.center,
children: [
// 设备类型图标(叠加在麦克风上)
// 设备类型图标
Icon(
icon,
color: isActive

2
local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/BleAgent.kt

@ -135,7 +135,7 @@ Log.d(TAG, "手动启动语音识别: ")
AgentService.pushAudioData(data)
// 可选:处理音频数据
}
override fun onAudioDataReceived1(data: ByteArray) {
override fun onAudioDataReceivedCall(data: ByteArray) {
}
/**

2
local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift

@ -1510,7 +1510,7 @@ extension AgentServiceImpl: BleService.Callback {
pushAudioData(data)
}
func onAudioDataReceived1(data: Data) {
func onAudioDataReceivedCall(data: Data) {
}

4
local_plugins/azure_speech/android/src/main/kotlin/com/yunqiinnovation/azure_speech/AzureSpeechPlugin.kt

@ -1003,9 +1003,9 @@ class AzureSpeechPlugin : BleService.Callback, FlutterPlugin {
// 可选:处理音频数据
}
override fun onAudioDataReceived1(data: ByteArray) {
override fun onAudioDataReceivedCall(data: ByteArray) {
// FileLogger.d(tag, "onAudioDataReceived1: ${data.size}")
// FileLogger.d(tag, "onAudioDataReceivedCall: ${data.size}")
azureAstHelper.pushAudioData(data)
// 可选:处理音频数据

2
local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureSpeechPlugin.swift

@ -947,7 +947,7 @@ extension AzureSpeechPlugin: BleService.Callback {
/// 接收到音频数据回调1
/// - Parameter data: 音频数据
public func onAudioDataReceived1(data: Data) {
public func onAudioDataReceivedCall(data: Data) {
// 安全解包版本
guard let audioStream = azureAstHelper.audioProcessor else {
os_log("音频流未初始化", type: .error)

2
local_plugins/azure_speech/ios/azure_speech/Sources/tools/MicrophoneCapture.swift

@ -318,7 +318,7 @@ public class MicrophoneCapture: NSObject {
// 转换成功且无错误
if status == .haveData, error == nil {
let data = strongSelf.audioBufferToData(convertedBuffer)
print("转换后数据长度: \(data.count)")
//print("转换后数据长度: \(data.count)")
strongSelf.audioDataHandler?(data)
}
}

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

@ -55,7 +55,7 @@ object BleService {
// 数据相关回调
fun onAudioDataReceived(data: ByteArray)
// 数据相关回调
fun onAudioDataReceived1(data: ByteArray)
fun onAudioDataReceivedCall(data: ByteArray)
// 唤醒信号相关回调
fun onWakeupSignalReceived()
@ -1995,7 +1995,7 @@ startBytesStatistics()
private fun notifyAudioDataReceived1(data: ByteArray) {
for (callback in callbacks) {
try {
callback.onAudioDataReceived1(data)
callback.onAudioDataReceivedCall(data)
} catch (e: Exception) {
Log.e(TAG, "分发音频数据回调异常", e)
}

2
local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleServicePlugin.kt

@ -361,7 +361,7 @@ class BleServicePlugin : FlutterPlugin, MethodCallHandler, ActivityAware,
// sendEvent(dataEventSink, mapOf("type" to "audioData", "data" to data), "发送音频数据异常")
}
override fun onAudioDataReceived1(data: ByteArray) {
override fun onAudioDataReceivedCall(data: ByteArray) {
// sendEvent(dataEventSink, mapOf("type" to "audioData", "data" to data), "发送音频数据异常")
}

6
local_plugins/ble_service/ios/ble_service/Sources/ble_service/BleService.swift

@ -28,7 +28,7 @@ public class BleService: NSObject {
// 数据相关回调
func onAudioDataReceived(data: Data)
func onAudioDataReceived1(data: Data)
func onAudioDataReceivedCall(data: Data)
// 唤醒信号回调
func onWakeupSignalReceived()
@ -532,7 +532,7 @@ private var cmdReplyType: UInt8 = 0
/// 通知所有回调接收到音频数据
private func notifyAudioDataReceived1(data: Data) {
for callback in callbacks {
callback.onAudioDataReceived1(data: data)
callback.onAudioDataReceivedCall(data: data)
}
}
@ -1189,7 +1189,7 @@ extension BleService: SwiftOpusAudioProcessor.AudioDataCallback {
}
/// 接收到解码后的PCM音频数据
func onAudioDataReceived1(data: Data) {
func onAudioDataReceivedCall(data: Data) {
notifyAudioDataReceived1(data: data)
}

2
local_plugins/ble_service/ios/ble_service/Sources/ble_service/SwiftBleServicePlugin.swift

@ -236,7 +236,7 @@ extension SwiftBleServicePlugin: BleService.Callback {
}
}
public func onAudioDataReceived1(data: Data) {
public func onAudioDataReceivedCall(data: Data) {
}

4
local_plugins/ble_service/ios/ble_service/Sources/ble_service/SwiftOpusAudioProcessor.swift

@ -9,7 +9,7 @@ class SwiftOpusAudioProcessor: NSObject {
/// 音频数据回调协议
protocol AudioDataCallback: AnyObject {
func onAudioDataReceived(data: Data)
func onAudioDataReceived1(data: Data)
func onAudioDataReceivedCall(data: Data)
func onEncodedDataReceived(data: Data) // 编码数据回调
}
@ -336,7 +336,7 @@ class SwiftOpusAudioProcessor: NSObject {
// 回调分离后的音频数据
DispatchQueue.main.async { [weak self] in
self?.callback?.onAudioDataReceived(data: rightBuffer)
self?.callback?.onAudioDataReceived1(data: leftBuffer)
self?.callback?.onAudioDataReceivedCall(data: leftBuffer)
}
}

2
local_plugins/ota/android/src/main/kotlin/com/example/ota/OtaPlugin.kt

@ -383,7 +383,7 @@ class OtaPlugin : BleService.Callback, FlutterPlugin, MethodCallHandler {
// 可选:处理音频数据
}
override fun onAudioDataReceived1(data: ByteArray) {
override fun onAudioDataReceivedCall(data: ByteArray) {
}
/**

2
pubspec.yaml

@ -1,7 +1,7 @@
name: voitrans
description: "Voitrans - AI Voice Assistant."
publish_to: "none"
version: 1.0.10+25
version: 1.0.12+29
environment:
sdk: ">=3.3.0 <4.0.0"

Loading…
Cancel
Save