@@ -2,14 +2,17 @@ import 'dart:async';
22import 'package:badgemagic/bademagic_module/bluetooth/connect_state.dart' ;
33import 'package:badgemagic/bademagic_module/bluetooth/datagenerator.dart' ;
44import 'package:badgemagic/providers/BadgeScanProvider.dart' ;
5- import 'package:flutter_blue_plus/flutter_blue_plus.dart' ;
5+ import 'package:universal_ble/universal_ble.dart' ;
6+ import '../../globals/globals.dart' ;
67import 'base_ble_state.dart' ;
78
89class ScanState extends NormalBleState {
910 final DataTransferManager manager;
1011 final BadgeScanMode mode;
1112 final List <String > allowedNames;
1213
14+ final String targetServiceUuid = serviceUuid;
15+
1316 ScanState ({
1417 required this .manager,
1518 required this .mode,
@@ -19,54 +22,51 @@ class ScanState extends NormalBleState {
1922 @override
2023 Future <BleState ?> processState () async {
2124 manager.clearConnectedDevice ();
22- await FlutterBluePlus .stopScan ();
25+ await UniversalBle .stopScan ();
2326
2427 toast.showToast ("Searching for device..." );
2528 Completer <BleState ?> nextStateCompleter = Completer ();
26- StreamSubscription <List <ScanResult >>? subscription;
29+ StreamSubscription <BleDevice >? subscription;
30+ Timer ? timeoutTimer;
2731
2832 bool isCompleted = false ;
2933 try {
30- subscription = FlutterBluePlus .scanResults .listen (
31- (results ) async {
32- if (isCompleted || results.isEmpty ) return ;
34+ subscription = UniversalBle .scanStream .listen (
35+ (device ) async {
36+ if (isCompleted) return ;
3337
3438 try {
3539 final normalizedAllowedNames = allowedNames
3640 .map ((e) => e.trim ().toLowerCase ())
3741 .where ((e) => e.isNotEmpty)
3842 .toList ();
3943
40- final foundDevice = results.firstWhere (
41- (result) {
42- final matchesUuid = result.advertisementData.serviceUuids
43- .contains (Guid ("0000fee0-0000-1000-8000-00805f9b34fb" ));
44-
45- final deviceName = result.device.name.trim ().toLowerCase ();
46- final matchesName = mode == BadgeScanMode .any ||
47- normalizedAllowedNames.contains (deviceName);
44+ final matchesUuid = device.services.contains (targetServiceUuid);
4845
49- return matchesUuid && matchesName;
50- },
51- orElse: () => throw Exception ("Matching device not found." ),
52- );
46+ final deviceName = (device.name ?? "" ).trim ().toLowerCase ();
47+ final matchesName = mode == BadgeScanMode .any ||
48+ normalizedAllowedNames.contains (deviceName);
5349
54- isCompleted = true ;
55- FlutterBluePlus .stopScan ();
56- toast.showToast ('Device found. Connecting...' );
50+ if (matchesUuid && matchesName) {
51+ isCompleted = true ;
52+ timeoutTimer? .cancel ();
53+ await UniversalBle .stopScan ();
54+ toast.showToast ('Device found. Connecting...' );
5755
58- nextStateCompleter.complete (ConnectState (
59- scanResult: foundDevice,
60- manager: manager,
61- ));
56+ nextStateCompleter.complete (ConnectState (
57+ scanResult: device,
58+ manager: manager,
59+ ));
60+ }
6261 } catch (e) {
63- logger.w ("No matching device found in this batch : $e " );
62+ logger.w ("Device discovered but filtered out : $e " );
6463 }
6564 },
6665 onError: (e) {
6766 if (! isCompleted) {
6867 isCompleted = true ;
69- FlutterBluePlus .stopScan ();
68+ timeoutTimer? .cancel ();
69+ UniversalBle .stopScan ();
7070 logger.e ("Scan error: $e " );
7171 toast.showErrorToast ('Scan error occurred.' );
7272 nextStateCompleter.completeError (
@@ -75,29 +75,30 @@ class ScanState extends NormalBleState {
7575 }
7676 },
7777 );
78- await FlutterBluePlus .startScan (
79- withServices: [Guid ("0000fee0-0000-1000-8000-00805f9b34fb" )],
80- removeIfGone: Duration (seconds: 5 ),
81- continuousUpdates: true ,
82- timeout: const Duration (seconds: 15 ), // Reduced scan timeout.
83- );
8478
85- await Future .delayed (const Duration (seconds: 1 ));
79+ await UniversalBle .startScan (
80+ scanFilter: ScanFilter (
81+ withServices: [targetServiceUuid],
82+ ),
83+ );
8684
87- if (! isCompleted) {
88- isCompleted = true ;
89- FlutterBluePlus .stopScan ();
90- toast.showErrorToast ('Device not found.' );
91- nextStateCompleter.completeError (Exception ('Device not found.' ));
92- }
85+ timeoutTimer = Timer (const Duration (seconds: 15 ), () async {
86+ if (! isCompleted) {
87+ isCompleted = true ;
88+ await UniversalBle .stopScan ();
89+ toast.showErrorToast ('Device not found.' );
90+ nextStateCompleter.completeError (Exception ('Device not found.' ));
91+ }
92+ });
9393
9494 return await nextStateCompleter.future;
9595 } catch (e) {
96+ timeoutTimer? .cancel ();
9697 logger.e ("Exception during scanning: $e " );
9798 throw Exception ("Please check if the device is turned on and retry." );
9899 } finally {
99100 await subscription? .cancel ();
100- await FlutterBluePlus .stopScan ();
101+ await UniversalBle .stopScan ();
101102 }
102103 }
103104}
0 commit comments