You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

323 lines
8.6 KiB

import 'dart:async';
import 'dart:typed_data';
import 'package:flutter/material.dart' hide ConnectionState;
import 'package:get/get.dart';
import 'package:jieli/jieli.dart';
/// 杰理测试控制器
class JieliTestController extends GetxController {
// Jieli插件实例
late Jieli jieli;
// 状态变量
var isScanning = false.obs;
var deviceInfo = '未获取'.obs;
var connectStatus = '未连接'.obs;
var currentDevice = Rx<BleDevice?>(null);
var scannedDevices = RxList<BleDevice>([]);
var wakeupReceived = false.obs;
var audioDataSize = 0.obs;
var receivedFrames = 0.obs;
var audioDataReceiving = false.obs;
var volumeCommandResult = ''.obs;
// 事件订阅
StreamSubscription? _scanSubscription;
StreamSubscription? _connectionSubscription;
StreamSubscription? _wakeupSubscription;
StreamSubscription? _audioSubscription;
StreamSubscription? _commandResultSubscription;
@override
void onInit() {
super.onInit();
_initializeJieli();
}
@override
void onClose() {
_cancelAllSubscriptions();
_disposeJieli();
super.onClose();
}
/// 取消所有订阅
void _cancelAllSubscriptions() {
_scanSubscription?.cancel();
_connectionSubscription?.cancel();
_wakeupSubscription?.cancel();
_audioSubscription?.cancel();
_commandResultSubscription?.cancel();
}
/// 初始化杰理SDK
void _initializeJieli() {
try {
jieli = Jieli();
_setupEventListeners();
} catch (e) {
// 初始化错误处理
}
}
/// 设置事件监听器
void _setupEventListeners() {
// 监听扫描结果
_scanSubscription = jieli.scanResults.listen((devices) {
scannedDevices.assignAll(devices);
});
// 监听连接状态
_connectionSubscription = jieli.connectionState.listen((state) {
switch (state) {
case ConnectionState.connected:
connectStatus.value = '已连接';
break;
case ConnectionState.disconnected:
connectStatus.value = '已断开';
currentDevice.value = null;
break;
case ConnectionState.connecting:
connectStatus.value = '连接中...';
break;
case ConnectionState.disconnecting:
connectStatus.value = '断开中...';
break;
case ConnectionState.error:
connectStatus.value = '连接错误';
break;
}
});
// 监听唤醒信号
_wakeupSubscription = jieli.wakeupStream.listen((wakeup) {
wakeupReceived.value = true;
Get.snackbar('收到唤醒信号', '耳机发送了唤醒信号');
});
// 监听音频数据
_audioSubscription = jieli.audioDataStream.listen((data) {
// 更新音频数据统计
audioDataSize.value += data.length;
receivedFrames.value++;
audioDataReceiving.value = true;
});
// 监听命令结果
_commandResultSubscription = jieli.commandResultStream.listen((result) {
// 处理音量调整命令结果
if (result.commandType == Jieli.commandTypeVolume) {
volumeCommandResult.value = result.success ? '音量调整成功' : '音量调整失败';
Get.snackbar(
result.success ? '音量调整成功' : '音量调整失败',
result.success ? '设备已更新音量' : '设备未能更新音量',
snackPosition: SnackPosition.BOTTOM,
backgroundColor: result.success ? Colors.green.withOpacity(0.7) : Colors.red.withOpacity(0.7),
colorText: Colors.white,
duration: Duration(seconds: 2),
);
}
});
}
/// 检查蓝牙状态
Future<bool> checkBluetoothStatus() async {
try {
final isEnabled = await jieli.isBluetoothEnabled();
if (!isEnabled) {
return await jieli.requestBluetoothEnable();
}
return true;
} catch (e) {
return false;
}
}
/// 开始扫描设备
Future<void> startScan() async {
if (isScanning.value) return;
final bluetoothReady = await checkBluetoothStatus();
if (!bluetoothReady) {
Get.snackbar('蓝牙未启用', '请启用蓝牙后再试');
return;
}
try {
isScanning.value = true;
// 清空之前的设备列表
scannedDevices.clear();
// 开始扫描,10秒后自动停止
final success = await jieli.startScan(scanTimeout: 10000);
if (!success) {
isScanning.value = false;
Get.snackbar('扫描失败', '启动扫描设备失败,请检查蓝牙权限');
}
// 10秒后自动更新UI状态
Future.delayed(Duration(milliseconds: 10000), () {
isScanning.value = false;
});
} catch (e) {
isScanning.value = false;
Get.snackbar('扫描错误', e.toString());
}
}
/// 停止扫描
Future<void> stopScan() async {
if (!isScanning.value) return;
try {
await jieli.stopScan();
isScanning.value = false;
} catch (e) {
// 停止扫描错误处理
}
}
/// 连接到指定设备
Future<void> connectToDevice(BleDevice device) async {
try {
// 先断开当前连接
if (currentDevice.value != null) {
await disconnectDevice();
}
// 更新UI状态
connectStatus.value = '连接中...';
// 重置音频和唤醒相关的状态
wakeupReceived.value = false;
audioDataSize.value = 0;
receivedFrames.value = 0;
audioDataReceiving.value = false;
// 连接设备
final success = await jieli.connect(device.id);
if (success) {
// 连接成功,更新当前设备
currentDevice.value = device;
deviceInfo.value = '设备名称: ${device.name}\n设备ID: ${device.id}\nRSSI: ${device.rssi} dBm';
} else {
deviceInfo.value = '连接失败';
}
} catch (e) {
deviceInfo.value = '连接错误: ${e.toString()}';
}
}
/// 断开设备连接
Future<void> disconnectDevice() async {
if (currentDevice.value == null) return;
try {
connectStatus.value = '断开中...';
final success = await jieli.disconnect();
if (success) {
deviceInfo.value = '未连接设备';
}
} catch (e) {
// 断开连接错误处理
}
}
/// 发送开始录音命令
Future<void> sendStartRecordingCommand() async {
if (currentDevice.value == null) {
Get.snackbar('操作失败', '未连接设备');
return;
}
try {
final success = await jieli.sendStartRecordingCommand();
if (success) {
Get.snackbar('命令已发送', '已发送开始录音命令');
} else {
Get.snackbar('命令发送失败', '发送开始录音命令失败');
}
} catch (e) {
Get.snackbar('命令错误', e.toString());
}
}
/// 发送停止录音命令
Future<void> sendStopRecordingCommand() async {
if (currentDevice.value == null) {
Get.snackbar('操作失败', '未连接设备');
return;
}
try {
final success = await jieli.sendStopRecordingCommand();
if (success) {
Get.snackbar('命令已发送', '已发送停止录音命令');
} else {
Get.snackbar('命令发送失败', '发送停止录音命令失败');
}
} catch (e) {
Get.snackbar('命令错误', e.toString());
}
}
/// 增加音量
Future<void> increaseVolume() async {
if (currentDevice.value == null) {
Get.snackbar('操作失败', '未连接设备');
return;
}
try {
volumeCommandResult.value = '发送中...';
final success = await jieli.increaseVolume();
if (!success) {
Get.snackbar('命令发送失败', '发送增加音量命令失败');
volumeCommandResult.value = '发送失败';
}
} catch (e) {
Get.snackbar('命令错误', e.toString());
volumeCommandResult.value = '发送出错';
}
}
/// 减小音量
Future<void> decreaseVolume() async {
if (currentDevice.value == null) {
Get.snackbar('操作失败', '未连接设备');
return;
}
try {
volumeCommandResult.value = '发送中...';
final success = await jieli.decreaseVolume();
if (!success) {
Get.snackbar('命令发送失败', '发送减小音量命令失败');
volumeCommandResult.value = '发送失败';
}
} catch (e) {
Get.snackbar('命令错误', e.toString());
volumeCommandResult.value = '发送出错';
}
}
/// 清理资源
void _disposeJieli() {
try {
jieli.dispose();
} catch (e) {
// 释放资源错误处理
}
}
}