-
Notifications
You must be signed in to change notification settings - Fork 195
/
devices_bloc.dart
116 lines (95 loc) · 3.83 KB
/
devices_bloc.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import 'dart:async';
import 'dart:io';
import 'package:fimber/fimber.dart';
import 'package:flutter_ble_lib_example/model/ble_device.dart';
import 'package:flutter_ble_lib_example/repository/device_repository.dart';
import 'package:flutter_ble_lib/flutter_ble_lib.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:rxdart/rxdart.dart';
class DevicesBloc {
final List<BleDevice> bleDevices = <BleDevice>[];
BehaviorSubject<List<BleDevice>> _visibleDevicesController =
BehaviorSubject<List<BleDevice>>.seeded(<BleDevice>[]);
StreamController<BleDevice> _devicePickerController =
StreamController<BleDevice>();
StreamSubscription<ScanResult> _scanSubscription;
StreamSubscription _devicePickerSubscription;
ValueObservable<List<BleDevice>> get visibleDevices =>
_visibleDevicesController.stream;
Sink<BleDevice> get devicePicker => _devicePickerController.sink;
DeviceRepository _deviceRepository;
BleManager _bleManager;
PermissionStatus _locationPermissionStatus = PermissionStatus.unknown;
Stream<BleDevice> get pickedDevice => _deviceRepository.pickedDevice
.skipWhile((bleDevice) => bleDevice == null);
DevicesBloc(this._deviceRepository, this._bleManager);
void _handlePickedDevice(BleDevice bleDevice) {
_deviceRepository.pickDevice(bleDevice);
}
void dispose() {
Fimber.d("cancel _devicePickerSubscription");
_devicePickerSubscription.cancel();
_visibleDevicesController.close();
_devicePickerController.close();
_scanSubscription?.cancel();
}
void init() {
Fimber.d("Init devices bloc");
bleDevices.clear();
_bleManager
.createClient(
restoreStateIdentifier: "example-restore-state-identifier",
restoreStateAction: (peripherals) {
peripherals?.forEach((peripheral) {
Fimber.d("Restored peripheral: ${peripheral.name}");
});
})
.catchError((e) => Fimber.d("Couldn't create BLE client", ex: e))
.then((_) => _checkPermissions())
.catchError((e) => Fimber.d("Permission check error", ex: e))
.then((_) => _startScan());
if (_visibleDevicesController.isClosed) {
_visibleDevicesController =
BehaviorSubject<List<BleDevice>>.seeded(<BleDevice>[]);
}
if (_devicePickerController.isClosed) {
_devicePickerController = StreamController<BleDevice>();
}
Fimber.d(" listen to _devicePickerController.stream");
_devicePickerSubscription =
_devicePickerController.stream.listen(_handlePickedDevice);
}
Future<void> _checkPermissions() async {
if (Platform.isAndroid) {
var permissionStatus = await PermissionHandler()
.requestPermissions([PermissionGroup.location]);
_locationPermissionStatus = permissionStatus[PermissionGroup.location];
if (_locationPermissionStatus != PermissionStatus.granted) {
return Future.error(Exception("Location permission not granted"));
}
}
}
void _startScan() {
Fimber.d("Ble client created");
_scanSubscription =
_bleManager.startPeripheralScan().listen((ScanResult scanResult) {
var bleDevice = BleDevice(scanResult);
if (scanResult.advertisementData.localName != null &&
!bleDevices.contains(bleDevice)) {
Fimber.d(
'found new device ${scanResult.advertisementData.localName} ${scanResult.peripheral.identifier}');
bleDevices.add(bleDevice);
_visibleDevicesController.add(bleDevices.sublist(0));
}
});
}
Future<void> refresh() async {
_scanSubscription.cancel();
await _bleManager.stopPeripheralScan();
bleDevices.clear();
_visibleDevicesController.add(bleDevices.sublist(0));
await _checkPermissions()
.then((_) => _startScan())
.catchError((e) => Fimber.d("Couldn't refresh", ex: e));
}
}