297 lines
8.1 KiB
Dart
297 lines
8.1 KiB
Dart
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<HomeScreen> createState() => _HomeScreenState();
|
|
}
|
|
|
|
class _HomeScreenState extends State<HomeScreen> {
|
|
List<BluetoothDevice> _systemDevices = [];
|
|
List<ScanResult> _scanResults = [];
|
|
bool _isScanning = false;
|
|
late StreamSubscription<List<ScanResult>> _scanResultsSubscription;
|
|
late StreamSubscription<bool> _isScanningSubscription;
|
|
|
|
bool _connected = false;
|
|
bool _found = false;
|
|
|
|
BluetoothDevice? device;
|
|
|
|
List<BluetoothService> _services = [];
|
|
|
|
Future<void> scanDevices() async {
|
|
if (await FlutterBluePlus.isSupported == false) {
|
|
print("Bluetooth not supported by this device");
|
|
return;
|
|
}
|
|
final scannedDevices = <ScanResult>{};
|
|
|
|
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<void> handleDisconnect() async {
|
|
await device?.disconnect();
|
|
}
|
|
|
|
Future onDisconnectPressed() async {
|
|
await handleDisconnect();
|
|
setState(() {
|
|
_connected = false;
|
|
});
|
|
}
|
|
|
|
@override
|
|
Future<void> 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<void>.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<int> 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<int> ledServiceValue = await ledService.read();
|
|
// print("READ Sense SERVICE: $ledServiceValue");
|
|
// print(
|
|
// "READ Sense SERVICE: ${String.fromCharCodes(ledServiceValue)}");
|
|
},
|
|
child: Text('Read Sense'),
|
|
)
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|