From 36e859d2fe431a27b388ac9d8a13ade921a375a7 Mon Sep 17 00:00:00 2001 From: Orangerot Date: Mon, 6 Jan 2025 19:21:36 +0100 Subject: feat: connect to ESense via AlertDialog --- android/app/src/main/AndroidManifest.xml | 13 ++++ lib/level_selection.dart | 122 ++++++++++++++++++++++++++++++- pubspec.lock | 57 +++++++++++++++ pubspec.yaml | 6 ++ 4 files changed, 197 insertions(+), 1 deletion(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 56d0153..1499c1a 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,4 +1,17 @@ + + + + + + + { String? stepmaniaCoursesPath; List stepmaniaCoursesFolders = []; + ESenseManager? eSenseManager; + String _deviceStatus = ''; + String eSenseDeviceName = ''; + bool connected = false; + bool sampling = false; + @override void initState() { super.initState(); loadFolderPath(); } + Future _askForPermissions() async { + if (!(await Permission.bluetoothScan.request().isGranted && + await Permission.bluetoothConnect.request().isGranted)) { + print( + 'WARNING - no permission to use Bluetooth granted. Cannot access eSense device.'); + } + // 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.'); + } + } + } + + Future _listenToESense() async { + await _askForPermissions(); + + // if you want to get the connection events when connecting, + // set up the listener BEFORE connecting... + eSenseManager!.connectionEvents.listen((event) { + print('CONNECTION event: $event'); + + // when we're connected to the eSense device, we can start listening to events from it + // if (event.type == ConnectionType.connected) _listenToESenseEvents(); + + setState(() { + connected = false; + switch (event.type) { + case ConnectionType.connected: + _deviceStatus = 'connected'; + connected = true; + break; + case ConnectionType.unknown: + _deviceStatus = 'unknown'; + break; + case ConnectionType.disconnected: + _deviceStatus = 'disconnected'; + sampling = false; + break; + case ConnectionType.device_found: + _deviceStatus = 'device_found'; + break; + case ConnectionType.device_not_found: + _deviceStatus = 'device_not_found'; + break; + } + }); + }); + } + + Future _connectToESense() async { + if (!connected) { + await _askForPermissions(); + print('Trying to connect to eSense device...'); + print(eSenseDeviceName); + eSenseManager = ESenseManager(eSenseDeviceName); + connected = await eSenseManager!.connect(); + print('success!'); + + setState(() { + _deviceStatus = connected ? 'connecting...' : 'connection failed'; + }); + _listenToESense(); + } + } + Future loadFolderPath() async { SharedPreferences prefs = await SharedPreferences.getInstance(); final String? stepmaniaCoursesPathSetting = @@ -68,7 +143,52 @@ class _LevelSelectionState extends State { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar(title: const Text('Sense the Rhythm')), + appBar: AppBar( + title: const Text('Sense the Rhythm'), + actions: [ + IconButton( + onPressed: () => showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text('Connect to ESense'), + content: StatefulBuilder(builder: + (BuildContext context, StateSetter setState) { + return 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('Discard'), + ), + TextButton( + onPressed: () => _connectToESense(), + child: const Text('Connect'), + ), + ], + ); + }, + ), + icon: const Icon(Icons.bluetooth)) + ], + ), body: Builder(builder: (context) { if (stepmaniaCoursesPath == null) { return Text('Add a Directory with Stepmania Songs on \'+\''); diff --git a/pubspec.lock b/pubspec.lock index 553fa2e..62488a6 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -121,6 +121,15 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.8" + esense_flutter: + dependency: "direct main" + description: + path: "packages/esense_flutter" + ref: master + resolved-ref: "3784963fcdeaebc4e81679dc331e3f195ecd1c42" + url: "https://github.com/cph-cachet/flutter-plugins.git" + source: git + version: "1.0.0" fake_async: dependency: transitive description: @@ -320,6 +329,54 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.0" + permission_handler: + dependency: "direct main" + description: + name: permission_handler + sha256: "18bf33f7fefbd812f37e72091a15575e72d5318854877e0e4035a24ac1113ecb" + url: "https://pub.dev" + source: hosted + version: "11.3.1" + permission_handler_android: + dependency: transitive + description: + name: permission_handler_android + sha256: "71bbecfee799e65aff7c744761a57e817e73b738fedf62ab7afd5593da21f9f1" + url: "https://pub.dev" + source: hosted + version: "12.0.13" + permission_handler_apple: + dependency: transitive + description: + name: permission_handler_apple + sha256: e6f6d73b12438ef13e648c4ae56bd106ec60d17e90a59c4545db6781229082a0 + url: "https://pub.dev" + source: hosted + version: "9.4.5" + permission_handler_html: + dependency: transitive + description: + name: permission_handler_html + sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24" + url: "https://pub.dev" + source: hosted + version: "0.1.3+5" + permission_handler_platform_interface: + dependency: transitive + description: + name: permission_handler_platform_interface + sha256: e9c8eadee926c4532d0305dff94b85bf961f16759c3af791486613152af4b4f9 + url: "https://pub.dev" + source: hosted + version: "4.2.3" + permission_handler_windows: + dependency: transitive + description: + name: permission_handler_windows + sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e" + url: "https://pub.dev" + source: hosted + version: "0.2.1" platform: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index c42d0a3..77e9319 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -14,6 +14,12 @@ dependencies: shared_preferences: ^2.3.4 file_picker: ^8.1.6 audioplayers: ^6.1.0 + esense_flutter: + git: + url: https://github.com/cph-cachet/flutter-plugins.git + ref: master + path: packages/esense_flutter/ + permission_handler: ^11.3.1 dev_dependencies: flutter_test: -- cgit v1.2.3