feat: check if bluetooth is enabled; ability to disconnect from ESense
This commit is contained in:
		
							parent
							
								
									4fb6af0135
								
							
						
					
					
						commit
						4c1d029216
					
				| 
						 | 
				
			
			@ -4,9 +4,7 @@
 | 
			
		|||
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
 | 
			
		||||
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
 | 
			
		||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
 | 
			
		||||
    <uses-permission
 | 
			
		||||
        android:name="android.permission.BLUETOOTH"
 | 
			
		||||
        android:maxSdkVersion="30" />
 | 
			
		||||
    <uses-permission android:name="android.permission.BLUETOOTH" />
 | 
			
		||||
    <uses-permission
 | 
			
		||||
        android:name="android.permission.BLUETOOTH_ADMIN"
 | 
			
		||||
        android:maxSdkVersion="30" />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,21 +29,30 @@ class ESenseInput {
 | 
			
		|||
    _listenToESense();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<void> _askForPermissions() async {
 | 
			
		||||
    if (!Platform.isAndroid && !Platform.isIOS) return;
 | 
			
		||||
  Future<bool> _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<void> 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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<String> deviceStatus;
 | 
			
		||||
 | 
			
		||||
  const ESenseConnectDialog(
 | 
			
		||||
      {super.key, required this.deviceStatus, required this.connect});
 | 
			
		||||
      {super.key,
 | 
			
		||||
      required this.deviceStatus,
 | 
			
		||||
      required this.connect,
 | 
			
		||||
      required this.disconnect});
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  State<ESenseConnectDialog> createState() => _ESenseConnectDialogState();
 | 
			
		||||
| 
						 | 
				
			
			@ -15,38 +21,43 @@ class _ESenseConnectDialogState extends State<ESenseConnectDialog> {
 | 
			
		|||
 | 
			
		||||
  @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: <Widget>[
 | 
			
		||||
        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: <Widget>[
 | 
			
		||||
              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'),
 | 
			
		||||
                    ),
 | 
			
		||||
            ],
 | 
			
		||||
          );
 | 
			
		||||
        });
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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();
 | 
			
		||||
          },
 | 
			
		||||
        );
 | 
			
		||||
      },
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue