import 'dart:async'; import 'package:badge/first_where_ext.dart'; import 'package:flutter/material.dart'; import 'package:flutter_blue_plus/flutter_blue_plus.dart'; import 'package:logger/logger.dart'; var logger = Logger(printer: PrettyPrinter()); class DeviceDetailsScreen extends StatefulWidget { final BluetoothDevice btDevice; const DeviceDetailsScreen({super.key, required this.btDevice}); @override State createState() { return DeviceDetailsState(); } } class DeviceDetailsState extends State { String connectStatus = ""; // Just to have a resonable default subscription? StreamSubscription subs = Stream.empty().listen((e) => ()); /// Whether the back button should be active. bool backActive = false; BluetoothCharacteristic? current; BluetoothCharacteristic? available; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Theme.of(context).colorScheme.inversePrimary, title: Text("Device details"), ), body: Center( child: Column( spacing: 20, children: [ Text(connectStatus), ElevatedButton( onPressed: backActive ? backClick : null, child: Text("Back"), ), ], ), ), ); } @override void initState() { super.initState(); _doConnect(); } void backClick() { Navigator.pop(context); } 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; subs.cancel().ignore(); subs = dev.connectionState.listen(onConnStateChange); try { logger.i("Try to connect..."); // connect timeout doesn't work under Linux await dev.connect().timeout(Duration(seconds: 2)); logger.i("Connected!"); connectStatus = "Connected"; // ???? WTF ???? List svcs = await dev.discoverServices(); dev.onServicesReset.listen((_) async { logger.i("Services Reset"); try { List svcs = await dev.discoverServices(); findCharac(svcs); } catch (e) { logger.e(e); } }); logger.i("services discovered"); findCharac(svcs); } catch (e) { logger.e(e); dev.disconnect().ignore(); connectStatus = e.toString(); } finally { backActive = true; if (mounted) { setState(() {}); } } } void findCharac(List svcs) { if (svcs.isEmpty) { connectStatus += ", No services found!"; return; } connectStatus += ", Services found!"; BluetoothService? badgeService = svcs.firstWhereOrNull( (s) => s.serviceUuid.str == "ca260000-b4bb-46b2-bd06-b7b7a61ea990", ); if (badgeService == null) { } else { logger.i("badge service found"); current = badgeService.characteristics.firstWhereOrNull( (c) => c.characteristicUuid.str == "ca260001-b4bb-46b2-bd06-b7b7a61ea990", ); available = badgeService.characteristics.firstWhereOrNull( (c) => c.characteristicUuid.str == "ca260002-b4bb-46b2-bd06-b7b7a61ea990", ); } if (current == null || available == null) { } else { logger.i("characteristics found"); } } }