import 'dart:async'; import 'package:auto_route/auto_route.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_blue_plus_windows/flutter_blue_plus_windows.dart'; @RoutePage() class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { return const HomeScreen(); } } class HomeScreen extends StatefulWidget { const HomeScreen({super.key}); @override State createState() => _HomeScreenState(); } class _HomeScreenState extends State { List _systemDevices = []; List _scanResults = []; bool _isScanning = false; late StreamSubscription> _scanResultsSubscription; late StreamSubscription _isScanningSubscription; bool _connected = false; bool _found = false; BluetoothDevice? device; List _services = []; Future scanDevices() async { if (await FlutterBluePlus.isSupported == false) { print("Bluetooth not supported by this device"); return; } final scannedDevices = {}; const timeout = Duration(seconds: 3); await FlutterBluePlus.startScan(timeout: timeout); final sub = FlutterBluePlus.scanResults.expand((e) => e).listen(scannedDevices.add); // await Future.delayed(timeout); sub.cancel(); scannedDevices.forEach(print); print('Scanned devices: ${scannedDevices.length}'); } @override void initState() { super.initState(); _scanResultsSubscription = FlutterBluePlus.scanResults.listen((results) { _scanResults = results; if (mounted) { setState(() {}); } }, onError: (e) { print('Scan Results Subscription Error: $e'); }); _isScanningSubscription = FlutterBluePlus.isScanning.listen((state) { _isScanning = state; if (mounted) { setState(() {}); } }); } @override void dispose() { _scanResultsSubscription.cancel(); _isScanningSubscription.cancel(); super.dispose(); } Future onScanPressed() async { try { _systemDevices = await FlutterBluePlus.systemDevices([]); } catch (e) { print('System Devices Error: $e'); } try { await FlutterBluePlus.startScan(timeout: const Duration(seconds: 15)); } catch (e) { print('Start Scan Error: $e'); } if (mounted) { setState(() {}); } } Future onConnectPressed() async { try { _systemDevices = await FlutterBluePlus.systemDevices([]); } catch (e) { print('System Devices Error: $e'); } try { await FlutterBluePlus.startScan(timeout: const Duration(seconds: 15)); } catch (e) { print('Start Scan Error: $e'); } FlutterBluePlus.scanResults.listen((results) async { for (ScanResult r in results) { if (kDebugMode) { print(r); } if (r.device.advName == "Go Bluetooth") { await FlutterBluePlus.stopScan(); device = r.device; print("FOUND BLUETOOTH DEVICE"); await device?.connect(); try { _services = await device?.discoverServices() ?? []; } catch (e) { print("Discover Services Error: $e"); } if (mounted) { setState(() { _connected = true; }); } } } }); } Future onStopPressed() async { try { FlutterBluePlus.stopScan(); } catch (e) { print('Stop Scan Error: $e'); } } Future onRefresh() { if (_isScanning == false) { FlutterBluePlus.startScan(timeout: const Duration(seconds: 15)); } if (mounted) { setState(() {}); } return Future.delayed(const Duration(milliseconds: 500)); } Future handleDisconnect() async { await device?.disconnect(); } Future onDisconnectPressed() async { await handleDisconnect(); setState(() { _connected = false; }); } @override Future deactivate() async { super.deactivate(); await handleDisconnect(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('XIAO Sense'), ), body: SingleChildScrollView( child: Column( children: [ // ListView.builder( // shrinkWrap: true, // physics: const NeverScrollableScrollPhysics(), // itemCount: _scanResults.length, // itemBuilder: (context, index) { // return ListTile( // title: Text(_scanResults[index].device.remoteId.toString()), // subtitle: Text(_scanResults[index].device.advName), // ); // }, // ), if (_connected) Text('Connected!'), ElevatedButton( // enabled: !_isScanning, onPressed: () async { // await Future.delayed(const Duration(seconds: 2)); // onScanPressed(); if (_connected) { onDisconnectPressed(); } else { onConnectPressed(); } }, // icon: _isScanning // ? const SizedBox.square( // dimension: 16, // child: CircularProgressIndicator(), // ) // : null, child: _isScanning ? const Text('Please wait') : _connected ? const Text('Disconnect') : const Text('Connect'), ), ElevatedButton( onPressed: () async { print('Toggle LED'); print(_services); final ledService = _services .where( (s) => s.serviceUuid == Guid('a0b40001-926d-4d61-98df-8c5c62ee53b3'), ) .first .characteristics .where((c) => c.characteristicUuid == Guid('a0b40002-926d-4d61-98df-8c5c62ee53b3')) .first; ledService.write([ 0, 1, 0, ]); // await Future.delayed(Duration(seconds: 2)); List ledServiceValue = await ledService.read(); print("READ LED SERVICE: $ledServiceValue"); }, child: Text('Toggle LED'), ), ElevatedButton( onPressed: () async { print('Toggle LED'); print(_services); final ledService = _services .where( (s) => s.serviceUuid == Guid('4c534d36-4453-3354-5253-657276696365'), ) .first .characteristics .where( (c) => c.characteristicUuid == Guid('61636365-6c65-7261-7469-6f6e44617461'), ) .first; final senseSubscription = ledService.onValueReceived.listen((value) { print("UPDATE: ${String.fromCharCodes(value)}"); }); device!.cancelWhenDisconnected(senseSubscription); await ledService.setNotifyValue(true); // await ledService.write([1, 2, 3]); // await Future.delayed(Duration(seconds: 2)); // List ledServiceValue = await ledService.read(); // print("READ Sense SERVICE: $ledServiceValue"); // print( // "READ Sense SERVICE: ${String.fromCharCodes(ledServiceValue)}"); }, child: Text('Read Sense'), ) ], ), ), ); } }