Browse Source

修改会议助手ble连接

weicu
tanlongsheng 1 year ago
parent
commit
504757fb78
  1. 83
      lib/modules/meeting/controllers/meeting_connect_controller.dart
  2. 51
      lib/modules/meeting/views/meeting_connect_view.dart

83
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,19 +47,25 @@ 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 {
await FlutterBluePlus.startScan( try {
timeout: const Duration(seconds: 15), isScanFailed = false;
withServices: [ await FlutterBluePlus.startScan(
Guid('FFF0'), timeout: const Duration(seconds: 15),
], withServices: [
withNames: ['AI PEN'], Guid('FFF0'),
); ],
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:
}
}
} }

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

@ -48,42 +48,42 @@ class MeetingConnectView extends GetView<MeetingConnectController> {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Obx( Obx(
() => Text( () => Padding(
controller.stateStr.value, padding: EdgeInsets.only(bottom: 30.w),
style: TextStyle( child: Text(
fontSize: 20.sp, controller.stateStr.value,
color: isDarkMode ? Colors.white : Colors.black, style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 20.sp,
color: isDarkMode ? Colors.white : Colors.black,
fontWeight: FontWeight.bold,
),
), ),
), ),
), ),
Obx( Obx(
() => controller.isRescan.value () => controller.isRescan.value
? Padding( ? _button('重新连接', Icons.refresh, onTap: () {
padding: EdgeInsets.only(top: 20.w), controller.startScan();
child: _button('重新连接', Icons.refresh, onTap: () { })
controller.startScan();
}),
)
: const SizedBox(), : const SizedBox(),
), ),
Obx( Obx(
() => controller.isImportedFiles.value () => Text(
? Padding( controller.importedFilesStr.value,
padding: EdgeInsets.only(top: 30.w), style: TextStyle(
child: Text( fontSize: 16.sp,
'检测到有新文件,是否导入', color: isDarkMode ? Colors.white70 : Colors.black54,
style: TextStyle( ),
fontSize: 16.sp, ),
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