main
1import 'dart:async';
2
3import 'package:blood_pressure_app/features/bluetooth/backend/bluetooth_backend.dart';
4import 'package:blood_pressure_app/logging.dart';
5import 'package:flutter/foundation.dart';
6import 'package:flutter_bloc/flutter_bloc.dart';
7
8part 'bluetooth_state.dart';
9
10/// Availability of the devices bluetooth adapter.
11///
12/// The only state that allows using the adapter is [BluetoothStateReady].
13class BluetoothCubit extends Cubit<BluetoothState> with TypeLogger {
14 /// Create a cubit connecting to the bluetooth module for availability.
15 ///
16 /// [manager] manager to check availabilty of.
17 BluetoothCubit({ required this.manager }):
18 super(BluetoothState.fromAdapterState(manager.lastKnownAdapterState)) {
19 _adapterStateSubscription = manager.stateStream.listen(_onAdapterStateChanged);
20
21 _lastKnownState = manager.lastKnownAdapterState;
22 logger.finer('lastKnownState: $_lastKnownState');
23 }
24
25 /// Bluetooth manager
26 late final BluetoothManager manager;
27 late BluetoothAdapterState _lastKnownState;
28 late StreamSubscription<BluetoothAdapterState> _adapterStateSubscription;
29
30 @override
31 Future<void> close() async {
32 await _adapterStateSubscription.cancel();
33 await super.close();
34 }
35
36 void _onAdapterStateChanged(BluetoothAdapterState state) async {
37 if (state == BluetoothAdapterState.unauthorized) {
38 final success = await manager.enable();
39 if (success != true) {
40 logger.warning('Enabling bluetooth failed or not needed on this platform');
41 }
42 }
43
44 _lastKnownState = state;
45 logger.finer('_onAdapterStateChanged(state: $state)');
46 emit(BluetoothState.fromAdapterState(state));
47 }
48
49 /// Request to enable bluetooth on the device
50 Future<bool?> enableBluetooth() async {
51 assert(state is BluetoothStateDisabled, 'No need to enable bluetooth when '
52 'already enabled or not known to be disabled.');
53 try {
54 return manager.enable();
55 } on Exception {
56 return false;
57 }
58 }
59
60 /// Reevaluate the current state.
61 ///
62 /// When the user is in another app like the device settings, sometimes
63 /// the app won't get notified about permission changes and such. In those
64 /// instances the user should have the option to manually recheck the state to
65 /// avoid getting stuck on a unauthorized state.
66 void forceRefresh() => _onAdapterStateChanged(_lastKnownState);
67}