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.
266 lines
7.5 KiB
266 lines
7.5 KiB
import 'dart:async';
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:flutter/services.dart';
|
|
|
|
/// BLE连接状态常量
|
|
class BleConnectionState {
|
|
static const int disconnected = 0;
|
|
static const int connecting = 1;
|
|
static const int connected = 2;
|
|
static const int disconnecting = 3;
|
|
static const int error = 4;
|
|
}
|
|
|
|
/// BLE服务插件
|
|
class BleService {
|
|
static final BleService _instance = BleService._internal();
|
|
|
|
/// 获取单例
|
|
factory BleService() => _instance;
|
|
|
|
// 方法通道
|
|
final MethodChannel _methodChannel = const MethodChannel('com.yunqiinnovation.ble_service');
|
|
|
|
// 事件通道 - 简化为只使用数据和状态通道
|
|
late final EventChannel _dataEventChannel;
|
|
late final EventChannel _statusEventChannel;
|
|
|
|
// 事件流
|
|
late final Stream<dynamic> _dataStream;
|
|
late final Stream<dynamic> _statusStream;
|
|
|
|
// 获取事件流
|
|
Stream<dynamic> get onDataReceived => _dataStream;
|
|
|
|
// 状态流直接传递原始数据
|
|
Stream<dynamic> get onStatusUpdated => _statusStream;
|
|
|
|
// 内部构造函数
|
|
BleService._internal() {
|
|
_dataEventChannel = const EventChannel('com.yunqiinnovation.ble_service/data_events');
|
|
_statusEventChannel = const EventChannel('com.yunqiinnovation.ble_service/status_events');
|
|
|
|
// 初始化事件流
|
|
_dataStream = _dataEventChannel.receiveBroadcastStream();
|
|
_statusStream = _statusEventChannel.receiveBroadcastStream();
|
|
}
|
|
|
|
/// 检查是否已连接
|
|
Future<bool> isConnected() async {
|
|
try {
|
|
final result = await _methodChannel.invokeMethod<bool>('isConnected');
|
|
return result ?? false;
|
|
} catch (e) {
|
|
print('检查连接状态失败: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// 获取电池电量
|
|
Future<int> getBatteryLevel() async {
|
|
try {
|
|
final result = await _methodChannel.invokeMethod<int>('getBatteryLevel');
|
|
return result ?? 0;
|
|
} catch (e) {
|
|
print('获取电池电量失败: $e');
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/// 获取设备版本信息
|
|
Future<bool> getDeviceVersion() async {
|
|
try {
|
|
final result = await _methodChannel.invokeMethod<bool>('getDeviceVersion');
|
|
return result ?? false;
|
|
} catch (e) {
|
|
print('获取设备版本失败: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// 获取电池信息
|
|
Future<bool> getBatteryInfo() async {
|
|
try {
|
|
final result = await _methodChannel.invokeMethod<bool>('getBatteryInfo');
|
|
return result ?? false;
|
|
} catch (e) {
|
|
print('获取电池信息失败: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// 打开编码器
|
|
Future<bool> openEncoder() async {
|
|
try {
|
|
final result = await _methodChannel.invokeMethod<bool>('openEncoder');
|
|
return result ?? false;
|
|
} catch (e) {
|
|
print('打开编码器失败: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// 打开解码器
|
|
Future<bool> openDecoder() async {
|
|
try {
|
|
final result = await _methodChannel.invokeMethod<bool>('openDecoder');
|
|
return result ?? false;
|
|
} catch (e) {
|
|
print('打开解码器失败: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// 关闭编解码器
|
|
Future<bool> closeCodec() async {
|
|
try {
|
|
final result = await _methodChannel.invokeMethod<bool>('closeCodec');
|
|
return result ?? false;
|
|
} catch (e) {
|
|
print('关闭编解码器失败: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// 播放A2DP
|
|
Future<bool> playA2DP() async {
|
|
try {
|
|
final result = await _methodChannel.invokeMethod<bool>('playA2DP');
|
|
return result ?? false;
|
|
} catch (e) {
|
|
print('播放A2DP失败: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// 启动BLE后台服务
|
|
/// [config] 配置参数,可包含:
|
|
/// - scan_interval: 扫描间隔时间(毫秒)
|
|
/// - scan_duration: 扫描持续时间(毫秒)
|
|
/// - notification_title: 通知标题
|
|
/// - notification_content: 通知内容
|
|
/// - mac: 设备地址
|
|
/// - device_name: 设备名称
|
|
Future<bool> startBleService(Map<String, dynamic> config) async {
|
|
try {
|
|
final result = await _methodChannel.invokeMethod<bool>('startBleService', config);
|
|
return result ?? false;
|
|
} catch (e) {
|
|
print('启动BLE后台服务失败: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// 停止BLE后台服务
|
|
Future<bool> stopBleService() async {
|
|
try {
|
|
final result = await _methodChannel.invokeMethod<bool>('stopBleService');
|
|
return result ?? false;
|
|
} catch (e) {
|
|
print('停止BLE后台服务失败: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// 注册BLE后台扫描
|
|
///
|
|
/// 注册后,即使应用被杀死,系统也会在检测到设备广播时唤醒应用
|
|
/// 这是确保设备可以在应用后台时被自动连接的关键功能
|
|
Future<bool> registerBackgroundScan() async {
|
|
try {
|
|
final result = await _methodChannel.invokeMethod<bool>('registerBackgroundScan');
|
|
return result ?? false;
|
|
} catch (e) {
|
|
print('注册后台扫描失败: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// 注销BLE后台扫描
|
|
///
|
|
/// 当不再需要后台扫描功能时调用,例如用户主动断开连接时
|
|
Future<bool> unregisterBackgroundScan() async {
|
|
try {
|
|
final result = await _methodChannel.invokeMethod<bool>('unregisterBackgroundScan');
|
|
return result ?? false;
|
|
} catch (e) {
|
|
print('注销后台扫描失败: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
//========================================================================
|
|
// 以下是ChatAgent相关功能
|
|
//========================================================================
|
|
|
|
/// 初始化语音交互代理
|
|
///
|
|
/// [config] 配置参数,必须包含:
|
|
/// - azureSpeechKey: Azure语音服务API密钥
|
|
/// - azureSpeechRegion: Azure语音服务区域
|
|
/// - openaiApiKey: OpenAI API密钥
|
|
/// - openaiBaseUrl: OpenAI API基础URL
|
|
/// - openaiModel: OpenAI模型名称,默认为'gpt-3.5-turbo'
|
|
Future<bool> initializeChatAgent(Map<String, dynamic> config) async {
|
|
try {
|
|
final result = await _methodChannel.invokeMethod<bool>('initializeChatAgent', config);
|
|
return result ?? false;
|
|
} catch (e) {
|
|
print('初始化语音交互代理失败: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// 启动语音识别
|
|
///
|
|
/// 用于手动启动语音识别,通常不需要直接调用,因为在唤醒时会自动启动
|
|
Future<bool> startListening() async {
|
|
try {
|
|
final result = await _methodChannel.invokeMethod<bool>('startListening');
|
|
return result ?? false;
|
|
} catch (e) {
|
|
print('启动语音识别失败: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// 停止语音识别
|
|
Future<bool> stopListening() async {
|
|
try {
|
|
final result = await _methodChannel.invokeMethod<bool>('stopListening');
|
|
return result ?? false;
|
|
} catch (e) {
|
|
print('停止语音识别失败: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// 处理文本输入
|
|
///
|
|
/// [text] 用户输入的文本
|
|
/// [speakResponse] 是否使用TTS朗读回复,默认为false
|
|
Future<bool> processTextInput(String text, {bool speakResponse = false}) async {
|
|
try {
|
|
final result = await _methodChannel.invokeMethod<bool>('processTextInput', {
|
|
'text': text,
|
|
'speakResponse': speakResponse,
|
|
});
|
|
return result ?? false;
|
|
} catch (e) {
|
|
print('处理文本输入失败: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// 停止TTS播放
|
|
Future<bool> stopTts() async {
|
|
try {
|
|
final result = await _methodChannel.invokeMethod<bool>('stopTts');
|
|
return result ?? false;
|
|
} catch (e) {
|
|
print('停止TTS播放失败: $e');
|
|
return false;
|
|
}
|
|
}
|
|
}
|