Browse Source

修改会议助手ble连接

newdev_shunjiawei
tanlongsheng 1 year ago
parent
commit
a9daf0938e
  1. 69
      lib/modules/meeting/controllers/meeting_connect_controller.dart
  2. 29
      lib/modules/meeting/views/meeting_connect_view.dart

69
lib/modules/meeting/controllers/meeting_connect_controller.dart

@ -7,11 +7,17 @@ class MeetingConnectController extends GetxController {
RxString stateStr = '搜索中...'.obs; RxString stateStr = '搜索中...'.obs;
RxBool isRescan = false.obs; RxBool isRescan = false.obs;
RxBool isImportedFiles = false.obs; RxBool isImportedFiles = false.obs;
RxString importedFilesStr = ''.obs;
late StreamSubscription<List<ScanResult>> _scanResultsSubscription; late StreamSubscription<List<ScanResult>> _scanResultsSubscription;
late StreamSubscription<bool> _isScanningSubscription; late StreamSubscription<bool> _isScanningSubscription;
BluetoothDevice? _device; BluetoothDevice? _device;
bool isScanFailed = false;
late BluetoothCharacteristic? _writeCharacteristic;
late StreamSubscription<List<int>>? _valueReceivedSubscription;
@override @override
void onInit() { void onInit() {
super.onInit(); super.onInit();
@ -21,6 +27,11 @@ class MeetingConnectController extends GetxController {
} }
}); });
_isScanningSubscription = FlutterBluePlus.isScanning.listen((state) { _isScanningSubscription = FlutterBluePlus.isScanning.listen((state) {
if (isScanFailed) {
stateStr.value = '搜索失败,请检查蓝牙是否开启';
isRescan.value = true;
return;
}
if (!state && _device == null) { if (!state && _device == null) {
stateStr.value = '未搜索到 AI PEN 设备'; stateStr.value = '未搜索到 AI PEN 设备';
isRescan.value = true; isRescan.value = true;
@ -36,12 +47,15 @@ class MeetingConnectController extends GetxController {
void onClose() { void onClose() {
_scanResultsSubscription.cancel(); _scanResultsSubscription.cancel();
_isScanningSubscription.cancel(); _isScanningSubscription.cancel();
_valueReceivedSubscription?.cancel();
_stopScan(); _stopScan();
_disconnect(); _disconnect();
super.onClose(); super.onClose();
} }
Future<void> startScan() async { Future<void> startScan() async {
try {
isScanFailed = false;
await FlutterBluePlus.startScan( await FlutterBluePlus.startScan(
timeout: const Duration(seconds: 15), timeout: const Duration(seconds: 15),
withServices: [ withServices: [
@ -49,6 +63,9 @@ class MeetingConnectController extends GetxController {
], ],
withNames: ['AI PEN'], withNames: ['AI PEN'],
); );
} catch (e) {
isScanFailed = true;
}
} }
Future<void> _stopScan() async { Future<void> _stopScan() async {
@ -57,6 +74,7 @@ class MeetingConnectController extends GetxController {
Future<void> _connect() async { Future<void> _connect() async {
await _device?.connect(); await _device?.connect();
await _discoverServices();
} }
Future<void> _disconnect() async { Future<void> _disconnect() async {
@ -71,4 +89,55 @@ class MeetingConnectController extends GetxController {
stateStr.value = '已连接到 AI PEN 设备'; stateStr.value = '已连接到 AI PEN 设备';
} }
} }
Future<void> _discoverServices() async {
List<BluetoothService> services = await _device?.discoverServices() ?? [];
if (services.isNotEmpty) {
for (var element in services) {
if (element.serviceUuid == Guid('FFF0')) {
_readCharacteristics(element.characteristics);
}
}
}
}
Future<void> _readCharacteristics(
List<BluetoothCharacteristic> characteristics) async {
for (var element in characteristics) {
if (element.characteristicUuid == Guid('FFF1')) {
_writeCharacteristic = element;
stateStr.value = '检查是否有新文件需要导入';
sendData([0x5a, 0x01, 0x0d]);
} else if (element.characteristicUuid == Guid('FFF2')) {
await element.setNotifyValue(true);
_valueReceivedSubscription = element.onValueReceived.listen((value) {
_listenData(value);
});
}
}
}
Future<void> sendData(List<int> value) async {
await _writeCharacteristic?.write(value, withoutResponse: true);
}
void _listenData(List<int> value) {
print('----$value--------');
int command = value[2];
switch (command) {
case 0x0d: // 是否有导入文件
if (value[3] == 0x01) {
isImportedFiles.value = true;
importedFilesStr.value = '检查到有新文件,是否导入';
} else {
isImportedFiles.value = false;
importedFilesStr.value = '没有新文件需要导入';
}
break;
case 0x87: // Wi-Fi 开启/关闭
if (value[2] == 0x01) {}
break;
default:
}
}
} }

29
lib/modules/meeting/views/meeting_connect_view.dart

@ -48,7 +48,9 @@ class MeetingConnectView extends GetView<MeetingConnectController> {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Obx( Obx(
() => Text( () => Padding(
padding: EdgeInsets.only(bottom: 30.w),
child: Text(
controller.stateStr.value, controller.stateStr.value,
style: TextStyle( style: TextStyle(
fontSize: 20.sp, fontSize: 20.sp,
@ -57,33 +59,31 @@ class MeetingConnectView extends GetView<MeetingConnectController> {
), ),
), ),
), ),
),
Obx( Obx(
() => controller.isRescan.value () => controller.isRescan.value
? Padding( ? _button('重新连接', Icons.refresh, onTap: () {
padding: EdgeInsets.only(top: 20.w),
child: _button('重新连接', Icons.refresh, onTap: () {
controller.startScan(); controller.startScan();
}), })
)
: const SizedBox(), : const SizedBox(),
), ),
Obx( Obx(
() => controller.isImportedFiles.value () => Text(
? Padding( controller.importedFilesStr.value,
padding: EdgeInsets.only(top: 30.w),
child: Text(
'检测到有新文件,是否导入',
style: TextStyle( style: TextStyle(
fontSize: 16.sp, fontSize: 16.sp,
color: isDarkMode ? Colors.white70 : Colors.black54, color: isDarkMode ? Colors.white70 : Colors.black54,
), ),
), ),
)
: const SizedBox(),
), ),
Obx( Obx(
() => controller.isImportedFiles.value () => controller.isImportedFiles.value
? _button('导入文件', Icons.file_download, onTap: () {}) ? Padding(
padding: EdgeInsets.symmetric(vertical: 10.w),
child: _button('导入文件', Icons.file_download, onTap: () {
controller.sendData([0x5a, 0x01, 0x0d]);
}),
)
: const SizedBox(), : const SizedBox(),
), ),
], ],
@ -97,7 +97,6 @@ class MeetingConnectView extends GetView<MeetingConnectController> {
child: Container( child: Container(
width: 150.w, width: 150.w,
height: 42.w, height: 42.w,
margin: EdgeInsets.symmetric(vertical: 10.w),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.black, color: Colors.black,
borderRadius: BorderRadius.circular(42.w), borderRadius: BorderRadius.circular(42.w),

Loading…
Cancel
Save