import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_blue_plus_windows/flutter_blue_plus_windows.dart'; import 'package:shadcn_ui/shadcn_ui.dart'; 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!'), ShadButton( 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'), ), ShadButton( 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'), ), ShadButton( onPressed: () async { print('Toggle LED'); print(_services); final ledService = _services .where( (s) => s.serviceUuid == Guid('a0b40003-926d-4d61-98df-8c5c62ee53b3'), ) .first .characteristics .where((c) => c.characteristicUuid == Guid('a0b40004-926d-4d61-98df-8c5c62ee53b3')) .first; // 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'), ) ], ), ), ); } }