diff options
author | uvok | 2025-07-22 09:44:17 +0200 |
---|---|---|
committer | uvok | 2025-07-22 09:44:17 +0200 |
commit | a94649aa974298538b3d9ecf0028f68ae5bdca4e (patch) | |
tree | 06fb9c4a61539633ef02aaf2492219e5af66bfe4 | |
parent | 53242a20032c054e854f2bf3d94f4a5bd10b0be3 (diff) |
Polish scanning and connecting
scan timeout.
state cleanup.
Use platformname
-rw-r--r-- | lib/device.dart | 46 | ||||
-rw-r--r-- | lib/main.dart | 44 |
2 files changed, 71 insertions, 19 deletions
diff --git a/lib/device.dart b/lib/device.dart index eb863ad..94b2899 100644 --- a/lib/device.dart +++ b/lib/device.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:flutter_blue_plus/flutter_blue_plus.dart'; import 'package:logger/logger.dart'; @@ -26,13 +28,26 @@ class DeviceScreen extends StatefulWidget { } class DeviceState extends State<DeviceScreen> { + String connectStatus = "<Status>"; + // ??? + StreamSubscription<BluetoothConnectionState> subs = + Stream<BluetoothConnectionState>.empty().listen((e) => ()); + bool backActive = false; + @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text("Device details")), body: Center( child: Column( - children: [ElevatedButton(onPressed: backClick, child: Text("Back"))], + spacing: 20, + children: [ + Text(connectStatus), + ElevatedButton( + onPressed: backActive ? backClick : null, + child: Text("Back"), + ), + ], ), ), ); @@ -49,20 +64,39 @@ class DeviceState extends State<DeviceScreen> { } void onConnStateChange(BluetoothConnectionState event) { + setState(() { + connectStatus = event.toString(); + }); logger.i("New conn state: ${event.toString()}"); } + @override + void deactivate() { + super.deactivate(); + logger.i("Closing state"); + subs.cancel().ignore(); + widget.btDevice.disconnect().ignore(); + } + void _doConnect() async { final dev = widget.btDevice; - var subs = dev.connectionState.listen(onConnStateChange); + subs.cancel().ignore(); + subs = dev.connectionState.listen(onConnStateChange); try { logger.i("Try to connect..."); - await dev.connect(); + // connect timeout doesn't work under Linux + await dev.connect().timeout(Duration(seconds: 1)); logger.i("Connected!"); - await dev.disconnect(); - logger.i("Disonnected!"); + + connectStatus = "Connected"; + } catch (e) { + dev.disconnect().ignore(); + connectStatus = e.toString(); } finally { - subs.cancel(); + backActive = true; + if (mounted) { + setState(() {}); + } } } } diff --git a/lib/main.dart b/lib/main.dart index aef85cf..23721ac 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -80,6 +80,14 @@ class _MyHomePageState extends State<MyHomePage> { } void _doScan() async { + var system = await FlutterBluePlus.systemDevices([]); + for (var d in system) { + logger.i('${d.platformName} already connected to! ${d.remoteId}'); + // if (d.platformName == "myBleDevice") { + // await r.connect(); // must connect our app + // } + } + setState(() { scanResults.clear(); isScanning = true; @@ -95,14 +103,14 @@ class _MyHomePageState extends State<MyHomePage> { if (Platform.isAndroid) { await FlutterBluePlus.startScan( withKeywords: ["NimBLE"], - timeout: Duration(seconds: 3), + timeout: Duration(seconds: 5), ); } else { // for Linux, which can't do advNames // msd doesn't work, either???? await FlutterBluePlus.startScan( - withMsd: [MsdFilter(0xffff, data: ascii.encode("uvok"))], - timeout: Duration(seconds: 3), + //withMsd: [MsdFilter(0xffff, data: ascii.encode("uvok"))], + timeout: Duration(seconds: 5), ); } @@ -116,15 +124,16 @@ class _MyHomePageState extends State<MyHomePage> { } } - void onScanResult(results) { + void onScanResult(List<ScanResult> results) { if (results.isNotEmpty) { - ScanResult r = results.last; // the most recently found device - logger.i( - '${r.device.remoteId}: "${r.device.advName}" / "${r.advertisementData.advName}" found!', - ); - setState(() { + //ScanResult r = results.last; // the most recently found device + for (var r in results.where((d) => d.rssi > -90)) { + logger.i( + '${r.device.remoteId}: "${r.device.platformName}" / "${r.device.advName}" / "${r.advertisementData.advName}" found!', + ); scanResults.add(r); - }); + } + setState(() {}); } } @@ -189,7 +198,9 @@ class _MyHomePageState extends State<MyHomePage> { // action in the IDE, or press "p" in the console), to see the // wireframe for each widget. mainAxisAlignment: MainAxisAlignment.center, + spacing: 24, children: <Widget>[ + SizedBox(height: 15), Row( mainAxisAlignment: MainAxisAlignment.center, spacing: 15.0, @@ -212,9 +223,12 @@ class _MyHomePageState extends State<MyHomePage> { itemBuilder: (context, index) { if (index >= scanResults.length) return null; final ScanResult result = scanResults[index]; - final String name = result.device.advName.isEmpty - ? ("<Unknown>") - : (result.device.advName); + final String name = firstGiven([ + result.device.advName, + result.device.platformName, + "<Unknown>", + ]); + return ListTile( title: Text(name), subtitle: Text(result.device.remoteId.str), @@ -241,3 +255,7 @@ class _MyHomePageState extends State<MyHomePage> { ); } } + +String firstGiven(List<String> list) { + return list.firstWhere((s) => s.isNotEmpty, orElse: () => ""); +} |