Commit b83a909e authored by Nicolas Richard Walter Boeckh's avatar Nicolas Richard Walter Boeckh 💬

Tweaks

Added:
- Main header
- Device class

Fixed:
- Share disabling on prefs reset
- Selection dialog state wonkyness
parent 8d46dd31
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"connectivity","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\connectivity-0.4.9+2\\\\","dependencies":[]},{"name":"flutter_blue","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_blue-0.7.2\\\\","dependencies":[]},{"name":"geolocator","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\geolocator-5.2.1\\\\","dependencies":["google_api_availability","location_permissions"]},{"name":"google_api_availability","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\google_api_availability-2.0.2\\\\","dependencies":[]},{"name":"location_permissions","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\location_permissions-2.0.4+1\\\\","dependencies":[]},{"name":"path_provider","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider-1.6.0\\\\","dependencies":[]},{"name":"permission_handler","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\permission_handler-4.2.0+hotfix.3\\\\","dependencies":[]},{"name":"shared_preferences","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences-0.5.7+2\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.2.0\\\\","dependencies":[]}],"android":[{"name":"connectivity","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\connectivity-0.4.9+2\\\\","dependencies":[]},{"name":"flutter_blue","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_blue-0.7.2\\\\","dependencies":[]},{"name":"geolocator","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\geolocator-5.2.1\\\\","dependencies":["google_api_availability","location_permissions"]},{"name":"google_api_availability","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\google_api_availability-2.0.2\\\\","dependencies":[]},{"name":"location_permissions","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\location_permissions-2.0.4+1\\\\","dependencies":[]},{"name":"path_provider","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider-1.6.0\\\\","dependencies":[]},{"name":"permission_handler","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\permission_handler-4.2.0+hotfix.3\\\\","dependencies":[]},{"name":"shared_preferences","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences-0.5.7+2\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.2.0\\\\","dependencies":[]}],"macos":[{"name":"connectivity_macos","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\connectivity_macos-0.1.0+4\\\\","dependencies":[]},{"name":"shared_preferences_macos","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences_macos-0.0.1+8\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.2.0\\\\","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"connectivity_for_web","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\connectivity_for_web-0.3.1+2\\\\","dependencies":[]},{"name":"shared_preferences_web","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences_web-0.1.2+5\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"connectivity","dependencies":["connectivity_macos","connectivity_for_web"]},{"name":"connectivity_for_web","dependencies":[]},{"name":"connectivity_macos","dependencies":[]},{"name":"flutter_blue","dependencies":[]},{"name":"geolocator","dependencies":["google_api_availability","location_permissions"]},{"name":"google_api_availability","dependencies":[]},{"name":"location_permissions","dependencies":[]},{"name":"path_provider","dependencies":[]},{"name":"permission_handler","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2020-09-07 01:52:18.814120","version":"1.21.0-10.0.pre.193"}
\ No newline at end of file
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"connectivity","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\connectivity-0.4.9+2\\\\","dependencies":[]},{"name":"flutter_blue","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_blue-0.7.2\\\\","dependencies":[]},{"name":"geolocator","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\geolocator-5.2.1\\\\","dependencies":["google_api_availability","location_permissions"]},{"name":"google_api_availability","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\google_api_availability-2.0.2\\\\","dependencies":[]},{"name":"location_permissions","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\location_permissions-2.0.4+1\\\\","dependencies":[]},{"name":"path_provider","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider-1.6.0\\\\","dependencies":[]},{"name":"permission_handler","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\permission_handler-4.2.0+hotfix.3\\\\","dependencies":[]},{"name":"shared_preferences","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences-0.5.7+2\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.2.0\\\\","dependencies":[]}],"android":[{"name":"connectivity","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\connectivity-0.4.9+2\\\\","dependencies":[]},{"name":"flutter_blue","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_blue-0.7.2\\\\","dependencies":[]},{"name":"geolocator","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\geolocator-5.2.1\\\\","dependencies":["google_api_availability","location_permissions"]},{"name":"google_api_availability","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\google_api_availability-2.0.2\\\\","dependencies":[]},{"name":"location_permissions","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\location_permissions-2.0.4+1\\\\","dependencies":[]},{"name":"path_provider","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider-1.6.0\\\\","dependencies":[]},{"name":"permission_handler","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\permission_handler-4.2.0+hotfix.3\\\\","dependencies":[]},{"name":"shared_preferences","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences-0.5.7+2\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.2.0\\\\","dependencies":[]}],"macos":[{"name":"connectivity_macos","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\connectivity_macos-0.1.0+4\\\\","dependencies":[]},{"name":"shared_preferences_macos","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences_macos-0.0.1+8\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.2.0\\\\","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"connectivity_for_web","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\connectivity_for_web-0.3.1+2\\\\","dependencies":[]},{"name":"shared_preferences_web","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences_web-0.1.2+5\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"connectivity","dependencies":["connectivity_macos","connectivity_for_web"]},{"name":"connectivity_for_web","dependencies":[]},{"name":"connectivity_macos","dependencies":[]},{"name":"flutter_blue","dependencies":[]},{"name":"geolocator","dependencies":["google_api_availability","location_permissions"]},{"name":"google_api_availability","dependencies":[]},{"name":"location_permissions","dependencies":[]},{"name":"path_provider","dependencies":[]},{"name":"permission_handler","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2020-09-09 00:35:24.671242","version":"1.21.0-10.0.pre.193"}
\ No newline at end of file
......@@ -6,11 +6,12 @@ import 'package:flutter_blue/flutter_blue.dart';
import 'package:kotlin_flavor/scope_functions.dart';
import 'package:logair_application/logic/handlers/bluetooth_wake_handler.dart';
import 'package:logair_application/logic/handlers/preference_handler.dart';
import 'package:logair_application/services/wake_service.dart';
import 'package:logair_application/utils/enums/bluetooth_connection_status.dart';
import 'package:logair_application/logic/handlers/data_handler.dart';
import 'package:logair_application/utils/enums/preference_keys.dart';
// TODO Attempt reacquiring device after 5 seconds inactivity.
/// Serves as a wrapper class around [FlutterBlue], and helps integrate it into the application with extensions
class BTLEHandler {
/// [Singleton]() instantiation factory.
......@@ -60,7 +61,7 @@ class BTLEHandler {
Stream<BluetoothConnectionStatus> getConnectionStatus() async* {
while (true) {
yield _bluetoothConnectionStatus;
await Future.delayed(Duration(seconds: 2));
await Future.delayed(Duration(milliseconds: 250));
}
}
......
......@@ -106,7 +106,7 @@ class PreferencesHandler {
/// This is a generic function to reset all preferences to their default values.
Future<void> resetAllPreferences() async {
PreferenceKeys.list.forEach(
PreferenceKeys.list.where((PreferenceKeys k) => k != PreferenceKeys.GEN__SHARE).forEach(
(PreferenceKeys e) async => await resetPreference(e.key)
);
}
......
......@@ -336,7 +336,7 @@ class _PreferencesWidgetState extends State<PreferencesWidget> {
),
padding: EdgeInsets.symmetric(vertical: 12),
onPressed: () async {
print('FormState validate : ${_formKey.currentState.validate()}');
//print('FormState validate : ${_formKey.currentState.validate()}');
if (_formKey.currentState.validate()) {
await PreferencesHandler().setPreferencesBool(PreferenceKeys.GEN__SHARE.key, _generalShareController.value);
......
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_blue/flutter_blue.dart';
import 'package:logair_application/localization/localization.dart';
import 'package:logair_application/logic/handlers/bluetooth_le_handler.dart';
import 'package:logair_application/ui/components/dialog/bluetooth_dialog/bluetooth_adapter_off.dart';
import 'package:logair_application/ui/components/dialog/bluetooth_dialog/adapter_unavailable.dart';
import 'package:logair_application/ui/components/dialog/bluetooth_dialog/selection_dialog.dart';
import 'package:logair_application/ui/components/dialog/bluetooth_dialog/bt_scan_tile.dart';
import 'package:logair_application/utils/device.dart';
class BluetoothDialog extends StatefulWidget {
BluetoothDialog({Key key}) : super(key: key);
......@@ -20,6 +22,8 @@ class _BluetoothDialogState extends State<BluetoothDialog> {
bool bluetoothAvailable = true;
bool bluetoothAvailabilityChecked = false;
BluetoothState state;
List<Device> _frequentDevices;
@override
Widget build(BuildContext context) {
......@@ -40,38 +44,108 @@ class _BluetoothDialogState extends State<BluetoothDialog> {
return SafeArea(
child: Scaffold(
body: Center(
child: Column(
children: <Widget>[
Expanded(
flex: 9,
child:
(bluetoothAvailable) ?
StreamBuilder<BluetoothState>(
stream: BTLEHandler().fblueInstance.state,
builder: (context, snapshot) {
final state = snapshot.data;
final Widget widget = (state == BluetoothState.on) ?
BluetoothSelectionDialog() :
BluetoothOffScreen(state: state);
return widget;
},
) :
BluetoothUnavailableScreen()
),
Expanded(
flex: 1,
child: Center(
child: RaisedButton(
onPressed: () => Navigator.of(context).pop(false),
child: Text("Back"),
appBar: AppBar(
title: Text(AppLocalization.of(context).bluetoothScanMessage),
actions: [
IconButton(
padding: EdgeInsets.all(10),
icon: Icon(Icons.refresh),
onPressed: () async {
if (await BTLEHandler().fblueInstance.isScanning.first)
BTLEHandler().fblueInstance.stopScan();
try {
await BTLEHandler().disconnect();
BTLEHandler().fblueInstance.startScan(timeout: Duration(seconds: 10));
} catch (e) { }
}
)
],
),
body: RefreshIndicator(
onRefresh: () async {
await BTLEHandler().disconnect();
BTLEHandler().fblueInstance.startScan();
},
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
padding: EdgeInsets.all(0),
child: Container(
child: Column(
children: <Widget>[
Text(
AppLocalization.of(context).bluetoothFrequent
),
StreamBuilder<List<ScanResult>>(
stream: BTLEHandler().fblueInstance.scanResults.transform(
new StreamTransformer.fromHandlers(
handleData: (List<ScanResult> list, EventSink<List<ScanResult>> sink) =>
sink.add(list.where((result) => _frequentDevices != null ? _frequentDevices.map((Device d) => d.address).contains(result.device.id.toString()) : false).toList())
)
),
initialData: [],
builder: (context, snapshot) => Column(
children: (snapshot.data.length > 0) ?
snapshot.data.map(
(result) => BTLEScanTile(
result: result,
onTap: () {
BTLEHandler().setDevice(result.device);
BTLEHandler().connect();
Navigator.of(context).pop(true);
}
),
).toList() : <Widget>[
Text(
AppLocalization.of(context).none,
style: Theme.of(context).textTheme.caption,
)
],
)
),
Divider(),
Text(
AppLocalization.of(context).bluetoothAvailable
),
StreamBuilder<List<ScanResult>>(
stream: BTLEHandler().fblueInstance.scanResults.transform(
new StreamTransformer.fromHandlers(
handleData: (List<ScanResult> list, EventSink<List<ScanResult>> sink) =>
sink.add(
list.where(
(result) =>
((_frequentDevices != null) ?
!_frequentDevices.map((Device d) => d.address).contains(result.device.id.toString())
: true) && result.device.name.length > 0).toList())
)
),
initialData: [],
builder: (context, snapshot) => Column(
children: (snapshot.data.length > 0) ?
snapshot.data.map(
(result) => BTLEScanTile(
result: result,
onTap: () {
BTLEHandler().fblueInstance.stopScan();
BTLEHandler().setDevice(result.device);
BTLEHandler().connect();
Navigator.of(context).pop(true);
}
),
).toList() : <Widget>[
Text(
"None",
style: Theme.of(context).textTheme.caption,
)
],
)
),
),
],
),
],
),
),
),
),
)
);
}
}
\ No newline at end of file
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_blue/flutter_blue.dart';
import 'package:logair_application/localization/localization.dart';
import 'package:logair_application/logic/handlers/bluetooth_le_handler.dart';
import 'package:logair_application/ui/components/common/base_widget.dart';
import 'package:logair_application/ui/components/dialog/bluetooth_dialog/bt_scan_tile.dart';
import 'package:logair_application/logic/handlers/preference_handler.dart';
class Device {
final String name;
final String address;
Device({this.name, this.address});
Device.fromJson(Map<String, dynamic> data) : name = data["name"], address = data["address"];
@override
String toString() => 'DEVICE $name@$address';
}
class BluetoothSelectionDialog extends StatefulWidget {
BluetoothSelectionDialog({Key key}) : super(key: key);
@override
_BluetoothSelectionDialogState createState() => _BluetoothSelectionDialogState();
}
class _BluetoothSelectionDialogState extends State<BluetoothSelectionDialog> {
_BluetoothSelectionDialogState();
List<Device> _frequentDevices;
@override
Widget build(BuildContext context) {
if (_frequentDevices != null)
setState(
() => this._frequentDevices = List.from(
json.decode((PreferencesHandler().getPreferencesString('BT.FREQUENT') ?? '[ ]'))
.map((device) => Device(name: device["name"], address: device["address"]))));
return BaseWidget(
builder: (context, sizingInfo) => Container(
height: sizingInfo.screenSize.height * 0.9,
child: RefreshIndicator(
onRefresh: () async {
await BTLEHandler().disconnect();
BTLEHandler().fblueInstance.startScan();
},
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
padding: EdgeInsets.all(0),
child: Container(
child: Column(
children: <Widget>[
ListTile(
leading: IconButton(
padding: EdgeInsets.all(0),
icon: Icon(Icons.arrow_back),
onPressed: () async {
if (await BTLEHandler().fblueInstance.isScanning.first)
BTLEHandler().fblueInstance.stopScan();
Navigator.of(context).pop(false);
},
),
title: Text(
AppLocalization.of(context).bluetoothScanMessage,
style: Theme.of(context).textTheme.headline6,
textAlign: TextAlign.center,
),
dense: true,
trailing: IconButton(
padding: EdgeInsets.all(0),
icon: Icon(Icons.refresh),
onPressed: () async {
if (await BTLEHandler().fblueInstance.isScanning.first)
BTLEHandler().fblueInstance.stopScan();
try {
await BTLEHandler().disconnect();
BTLEHandler().fblueInstance.startScan(timeout: Duration(seconds: 10));
} catch (e) { }
},
),
),
Divider(),
Text(
AppLocalization.of(context).bluetoothFrequent
),
StreamBuilder<List<ScanResult>>(
stream: BTLEHandler().fblueInstance.scanResults.transform(
new StreamTransformer.fromHandlers(
handleData: (List<ScanResult> list, EventSink<List<ScanResult>> sink) =>
sink.add(list.where((result) => _frequentDevices != null ? _frequentDevices.map((Device d) => d.address).contains(result.device.id.toString()) : false).toList())
)
),
initialData: [],
builder: (context, snapshot) => Column(
children: (snapshot.data.length > 0) ?
snapshot.data.map(
(result) => BTLEScanTile(
result: result,
onTap: () {
BTLEHandler().setDevice(result.device);
BTLEHandler().connect();
Navigator.of(context).pop(true);
}
),
).toList() : <Widget>[
Text(
AppLocalization.of(context).none,
style: Theme.of(context).textTheme.caption,
)
],
)
),
Divider(),
Text(
AppLocalization.of(context).bluetoothAvailable
),
StreamBuilder<List<ScanResult>>(
stream: BTLEHandler().fblueInstance.scanResults.transform(
new StreamTransformer.fromHandlers(
handleData: (List<ScanResult> list, EventSink<List<ScanResult>> sink) =>
sink.add(
list.where(
(result) =>
((_frequentDevices != null) ?
!_frequentDevices.map((Device d) => d.address).contains(result.device.id.toString())
: true) && result.device.name.length > 0).toList())
)
),
initialData: [],
builder: (context, snapshot) => Column(
children: (snapshot.data.length > 0) ?
snapshot.data.map(
(result) => BTLEScanTile(
result: result,
onTap: () {
BTLEHandler().fblueInstance.stopScan();
BTLEHandler().setDevice(result.device);
BTLEHandler().connect();
Navigator.of(context).pop(true);
}
),
).toList() : <Widget>[
Text(
"None",
style: Theme.of(context).textTheme.caption,
)
],
)
),
],
),
),
),
),
),
);
}
}
\ No newline at end of file
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:logair_application/ui/animation/forward_animation.dart';
import 'package:logair_application/logic/handlers/bluetooth_le_handler.dart';
import 'package:logair_application/ui/animation/forward_animation.dart';
import 'package:logair_application/ui/components/dialog/bluetooth_dialog/dialog.dart';
import 'package:logair_application/utils/enums/bluetooth_connection_status.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
/// Button enabling the app to connect to a PM detector device.
class BluetoothButton extends StatefulWidget {
BluetoothButton({Key key}) : super(key: key);
......@@ -18,112 +16,104 @@ class BluetoothButton extends StatefulWidget {
class _BluetoothButtonState extends State<BluetoothButton> {
_BluetoothButtonState({Key key});
Color _color;
IconData _icon = Icons.link;
MaterialColor _statusColor = Colors.blue;
int _colorOffset = 0;
BluetoothConnectionStatus _status;
// Can ignore dart(cancel_subscriptions) because linter error, subscription canceled in dispose.
// ignore: cancel_subscriptions
StreamSubscription<BluetoothConnectionStatus> _connectionStatusListener;
/// This [Function] enables non-dirty transitions, only on value change, reducing overhead.
void connectionStatusStateChanger(BluetoothConnectionStatus newStatus) {
if (mounted && newStatus != _status) {
Color newColor;
switch (newStatus) {
case BluetoothConnectionStatus.BTSTATUS_NOT_STREAMING:
newColor = Colors.grey[350];
break;
case BluetoothConnectionStatus.BTSTATUS_DISCOVERING_SERVICES:
newColor = Colors.blue[100];
break;
case BluetoothConnectionStatus.BTSTATUS_GETTING_CHARACTERISTICS:
newColor = Colors.blue[200];
break;
case BluetoothConnectionStatus.BTSTATUS_SETTING_MTU:
newColor = Colors.blue[300];
break;
case BluetoothConnectionStatus.BTSTATUS_STREAMING:
newColor = Colors.blueAccent;
break;
default:
}
setState(() {
_color = newColor;
_status = newStatus;
});
}
}
@override
void initState() {
super.initState();
this._connectionStatusListener = BTLEHandler().getConnectionStatus().listen(connectionStatusStateChanger);
}
BTLEHandler().getConnectionStatus().listen((BluetoothConnectionStatus btcs) {
if (mounted && btcs != this._status) {
Color newColor = _statusColor;
int newOffset = _colorOffset;
IconData newIcon = _icon;
print('$btcs -> $newColor,$newOffset, $newIcon');
switch(btcs) {
case BluetoothConnectionStatus.BTSTATUS_NOT_STREAMING:
newColor = Colors.grey;
newOffset = 0;
newIcon = Icons.link;
break;
case BluetoothConnectionStatus.BTSTATUS_DISCOVERING_SERVICES:
newColor = Colors.green;
newOffset = 100;
newIcon = Icons.bluetooth_searching;
break;
case BluetoothConnectionStatus.BTSTATUS_GETTING_CHARACTERISTICS:
newColor = Colors.yellow;
newOffset = 100;
newIcon = MdiIcons.bluetoothTransfer;
break;
case BluetoothConnectionStatus.BTSTATUS_SETTING_MTU:
newColor = Colors.blue;
newOffset = 200;
newIcon = MdiIcons.bluetoothTransfer;
break;
case BluetoothConnectionStatus.BTSTATUS_STREAMING:
newColor = Colors.blue;
newOffset = 300;
newIcon = Icons.bluetooth_connected;
break;
default:
newColor = Colors.grey;
newOffset = 0;
newIcon = Icons.link;
_status = BluetoothConnectionStatus.BTSTATUS_NOT_STREAMING;
}
setState(() {
_status = btcs;
_colorOffset = newOffset;
_statusColor = newColor;
_icon = newIcon;
});
}
@override
Future<void> dispose() async {
this._connectionStatusListener.cancel();
this._connectionStatusListener = null;
super.dispose();
});
}
@override
Widget build(BuildContext context) {
return Material(
color: Colors.transparent,
child: StreamBuilder<BluetoothConnectionStatus>(
stream: BTLEHandler().getConnectionStatus(),
initialData: BluetoothConnectionStatus.BTSTATUS_NOT_STREAMING,
builder: (context, snapshot) {
BluetoothConnectionStatus _bluetoothStatus = snapshot.data;
return Ink(
decoration: BoxDecoration(
border: Border.all(
color: Colors.white,
width: 2.0,
),
shape: BoxShape.circle,
return InkWell(
onTap: () {
print('Status $_status');
print("onTap");
if (_status == BluetoothConnectionStatus.BTSTATUS_NOT_STREAMING) {
print("Tap On");
Navigator.push(
context,
PopForwardRoute(
page: BluetoothDialog(),
),
child: Ink(
decoration: BoxDecoration(
border: Border.all(
color: Colors.indigoAccent,
width: 2.0,
),
color: _color,
shape: BoxShape.circle,
),
child: InkWell(
borderRadius: BorderRadius.circular(100.0),
onTap: () {
print("onTap");
if (_bluetoothStatus != BluetoothConnectionStatus.BTSTATUS_STREAMING) {
print("Tap On");
Navigator.push(
context,
PopForwardRoute(
page: BluetoothDialog(),
),
);
return true;
} else {
BTLEHandler().disconnect();
print('Tap off');
return true;
}
},
child: Padding(
padding: EdgeInsets.all(10),
child: Icon(
Icons.bluetooth,
color: Colors.white,
size: 30.0,
),
),
)
)
);
return true;
} else {
BTLEHandler().disconnect();
print('Tap off');
return true;
}
},
child: Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: RadialGradient(
center: Alignment.center,
colors: [
Colors.blue[50],
_statusColor[300 + _colorOffset],
_statusColor[200 + _colorOffset],
_statusColor[50 + _colorOffset] ?? _statusColor[100 + _colorOffset],
_statusColor[50 + _colorOffset] ?? _statusColor[100 + _colorOffset],
_statusColor[200 + _colorOffset],
_statusColor[300 + _colorOffset],
Colors.blue[50]
],
stops: [0, 0.05, 0.1, 0.2, 0.8, 0.9, 0.95, 1]
)
),
child: Icon(this._icon, size: 30,),