From 4c1d029216c29f786f12fa278b9dd7bf39129235 Mon Sep 17 00:00:00 2001 From: Orangerot Date: Mon, 13 Jan 2025 20:00:27 +0100 Subject: [PATCH] feat: check if bluetooth is enabled; ability to disconnect from ESense --- android/app/src/main/AndroidManifest.xml | 4 +- lib/utils/esense_input.dart | 16 ++++- lib/widgets/connection_status_button.dart | 12 ++-- lib/widgets/esense_connect_dialog.dart | 79 +++++++++++++---------- lib/widgets/level_list_entry.dart | 12 ++-- 5 files changed, 75 insertions(+), 48 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 0ba4ed0..9ba7706 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -4,9 +4,7 @@ - + diff --git a/lib/utils/esense_input.dart b/lib/utils/esense_input.dart index 4edb983..6eb4222 100644 --- a/lib/utils/esense_input.dart +++ b/lib/utils/esense_input.dart @@ -29,21 +29,30 @@ class ESenseInput { _listenToESense(); } - Future _askForPermissions() async { - if (!Platform.isAndroid && !Platform.isIOS) return; + Future _askForPermissions() async { + if (!Platform.isAndroid && !Platform.isIOS) return false; + if (!await Permission.bluetooth.serviceStatus.isEnabled) { + deviceStatus.value = "Bluetooth is disabled!"; + return false; + } if (!(await Permission.bluetoothScan.request().isGranted && await Permission.bluetoothConnect.request().isGranted && await Permission.bluetooth.request().isGranted)) { print( 'WARNING - no permission to use Bluetooth granted. Cannot access eSense device.'); + deviceStatus.value = "Insufficiant Permissions"; + return false; } // for some strange reason, Android requires permission to location for Bluetooth to work.....? if (Platform.isAndroid) { if (!(await Permission.locationWhenInUse.request().isGranted)) { print( 'WARNING - no permission to access location granted. Cannot access eSense device.'); + deviceStatus.value = "Insufficiant Permissions"; + return false; } } + return true; } void _listenToESense() { @@ -151,7 +160,8 @@ class ESenseInput { Future connectToESense(String deviceName) async { if (!connected) { - await _askForPermissions(); + bool permissionSuccessfull = await _askForPermissions(); + if (!permissionSuccessfull) return; print('Trying to connect to eSense device namend \'$deviceName\''); eSenseDeviceName = deviceName; eSenseManager.deviceName = deviceName; diff --git a/lib/widgets/connection_status_button.dart b/lib/widgets/connection_status_button.dart index ce3e662..e0c4cb4 100644 --- a/lib/widgets/connection_status_button.dart +++ b/lib/widgets/connection_status_button.dart @@ -21,10 +21,14 @@ class ConnectionStatusButton extends StatelessWidget { context: context, builder: (BuildContext context) { return ESenseConnectDialog( - deviceStatus: ESenseInput.instance.deviceStatus, - connect: (String name) { - ESenseInput.instance.connectToESense(name); - }); + deviceStatus: ESenseInput.instance.deviceStatus, + connect: (String name) { + ESenseInput.instance.connectToESense(name); + }, + disconnect: () { + ESenseInput.instance.eSenseManager.disconnect(); + }, + ); }, ), label: Text(deviceStatus), diff --git a/lib/widgets/esense_connect_dialog.dart b/lib/widgets/esense_connect_dialog.dart index bb9305b..8320dd4 100644 --- a/lib/widgets/esense_connect_dialog.dart +++ b/lib/widgets/esense_connect_dialog.dart @@ -1,10 +1,16 @@ import 'package:flutter/material.dart'; +import 'package:sense_the_rhythm/utils/esense_input.dart'; class ESenseConnectDialog extends StatefulWidget { final void Function(String) connect; + final VoidCallback disconnect; final ValueNotifier deviceStatus; + const ESenseConnectDialog( - {super.key, required this.deviceStatus, required this.connect}); + {super.key, + required this.deviceStatus, + required this.connect, + required this.disconnect}); @override State createState() => _ESenseConnectDialogState(); @@ -15,38 +21,43 @@ class _ESenseConnectDialogState extends State { @override Widget build(BuildContext context) { - return AlertDialog( - title: const Text('Connect to ESense'), - content: Column(mainAxisSize: MainAxisSize.min, children: [ - TextField( - onChanged: (input) { - setState(() { - eSenseDeviceName = input; - }); - }, - decoration: InputDecoration( - border: OutlineInputBorder(), - hintText: 'eSense-xxxx', - labelText: 'Device name', - ), - ), - // Text(eSenseDeviceName), - ValueListenableBuilder( - valueListenable: widget.deviceStatus, - builder: (BuildContext context, String value, Widget? child) { - return Text(value); - }), - ]), - actions: [ - TextButton( - onPressed: () => Navigator.pop(context, 'Cancel'), - child: const Text('Close'), - ), - TextButton( - onPressed: () => widget.connect(eSenseDeviceName), - child: const Text('Connect'), - ), - ], - ); + return ValueListenableBuilder( + valueListenable: widget.deviceStatus, + builder: (BuildContext context, String deviceStatus, Widget? child) { + return AlertDialog( + title: const Text('Connect to ESense'), + content: Column(mainAxisSize: MainAxisSize.min, children: [ + TextField( + onChanged: (input) { + setState(() { + eSenseDeviceName = input; + }); + }, + decoration: InputDecoration( + border: OutlineInputBorder(), + hintText: 'eSense-xxxx', + labelText: 'Device name', + ), + ), + // Text(eSenseDeviceName), + Text(deviceStatus) + ]), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context, 'Cancel'), + child: const Text('Close'), + ), + ESenseInput.instance.connected + ? TextButton( + onPressed: () => widget.disconnect(), + child: const Text('Disconnect'), + ) + : TextButton( + onPressed: () => widget.connect(eSenseDeviceName), + child: const Text('Connect'), + ), + ], + ); + }); } } diff --git a/lib/widgets/level_list_entry.dart b/lib/widgets/level_list_entry.dart index a47a9c2..832186f 100644 --- a/lib/widgets/level_list_entry.dart +++ b/lib/widgets/level_list_entry.dart @@ -25,10 +25,14 @@ class LevelListEntry extends StatelessWidget { context: context, builder: (BuildContext context) { return ESenseConnectDialog( - deviceStatus: ESenseInput.instance.deviceStatus, - connect: (String name) { - ESenseInput.instance.connectToESense(name); - }); + deviceStatus: ESenseInput.instance.deviceStatus, + connect: (String name) { + ESenseInput.instance.connectToESense(name); + }, + disconnect: () { + ESenseInput.instance.eSenseManager.disconnect(); + }, + ); }, ); }