|
@@ -4,16 +4,16 @@ import 'dart:typed_data';
|
|
|
import 'dart:convert';
|
|
|
import 'package:flutter/material.dart';
|
|
|
import 'package:flutter_bluetooth_serial/flutter_bluetooth_serial.dart';
|
|
|
+import 'bluetooth.dart';
|
|
|
|
|
|
class ConnectionPage extends StatefulWidget {
|
|
|
- const ConnectionPage({super.key});
|
|
|
+ final DeviceSelectionWrapper currentState;
|
|
|
+ const ConnectionPage({super.key, required this.currentState});
|
|
|
|
|
|
@override
|
|
|
State<ConnectionPage> createState() => _ConnectionPage();
|
|
|
}
|
|
|
|
|
|
-void printDiscovered() {}
|
|
|
-
|
|
|
List<BluetoothDiscoveryResult> scanBluetoothDevice(
|
|
|
List<BluetoothDiscoveryResult> results) {
|
|
|
print("Scanning started!");
|
|
@@ -30,78 +30,222 @@ List<BluetoothDiscoveryResult> scanBluetoothDevice(
|
|
|
return results;
|
|
|
}
|
|
|
|
|
|
+Widget generateDiscoveredBluetoothList(
|
|
|
+ List<BluetoothDevice> bondedDevices, Function callback) {
|
|
|
+ List<Widget> devs = [];
|
|
|
+ for (int i = 0; i < bondedDevices.length; i++) {
|
|
|
+ BluetoothDevice thisDevice = bondedDevices[i];
|
|
|
+ devs.add(Container(
|
|
|
+ margin: EdgeInsetsDirectional.all(4),
|
|
|
+ color: Colors.white,
|
|
|
+ child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
|
|
|
+ Container(
|
|
|
+ alignment: Alignment.center,
|
|
|
+ padding: EdgeInsetsDirectional.all(14),
|
|
|
+ child: Image.asset('assets/images/bt.png')),
|
|
|
+ Container(
|
|
|
+ alignment: Alignment.center,
|
|
|
+ padding: EdgeInsetsDirectional.all(14),
|
|
|
+ child: Column(
|
|
|
+ mainAxisAlignment: MainAxisAlignment.center,
|
|
|
+ children: [
|
|
|
+ Text(
|
|
|
+ thisDevice.address,
|
|
|
+ textAlign: TextAlign.left,
|
|
|
+ ),
|
|
|
+ Text(
|
|
|
+ thisDevice.name!,
|
|
|
+ textAlign: TextAlign.left,
|
|
|
+ )
|
|
|
+ ],
|
|
|
+ )),
|
|
|
+ Container(
|
|
|
+ alignment: Alignment.center,
|
|
|
+ padding: EdgeInsetsDirectional.all(14),
|
|
|
+ child: ElevatedButton(
|
|
|
+ style: ElevatedButton.styleFrom(),
|
|
|
+ onPressed: () {
|
|
|
+ callback(thisDevice.address, thisDevice.name!);
|
|
|
+ },
|
|
|
+ child: const Text('選擇'),
|
|
|
+ ))
|
|
|
+ ])));
|
|
|
+ }
|
|
|
+ return Container(
|
|
|
+ height: 400,
|
|
|
+ padding: EdgeInsetsDirectional.all(4),
|
|
|
+ decoration: BoxDecoration(
|
|
|
+ border: Border.all(
|
|
|
+ color: Color.fromARGB(255, 226, 226, 226),
|
|
|
+ ),
|
|
|
+ borderRadius: BorderRadius.all(Radius.circular(4))),
|
|
|
+ child: SingleChildScrollView(
|
|
|
+ child: Column(
|
|
|
+ children: devs,
|
|
|
+ )));
|
|
|
+}
|
|
|
+
|
|
|
class _ConnectionPage extends State<ConnectionPage> {
|
|
|
- late BluetoothConnection connection;
|
|
|
- bool _isConnected = false;
|
|
|
- var _latestDiscoveredId = "Nothing Yet";
|
|
|
+ //Bluetooth Connection Related
|
|
|
+ List<BluetoothDevice> bondedDevices = <BluetoothDevice>[];
|
|
|
+ DeviceSelectionWrapper operatingDevice = DeviceSelectionWrapper();
|
|
|
+ String _statusText = "請選擇並連接到一個 Bluetooth Serial 裝置";
|
|
|
|
|
|
@override
|
|
|
Widget build(BuildContext context) {
|
|
|
+ operatingDevice = widget.currentState;
|
|
|
+ //Check if it is connected
|
|
|
+ if (operatingDevice.deviceConnected) {
|
|
|
+ setState(() {
|
|
|
+ _statusText = "已連接到裝置 " +
|
|
|
+ operatingDevice.deviceName +
|
|
|
+ " (" +
|
|
|
+ operatingDevice.deviceAddr +
|
|
|
+ ")";
|
|
|
+ });
|
|
|
+ }
|
|
|
+ //Load all the bluetooth device on screen load
|
|
|
+ FlutterBluetoothSerial.instance
|
|
|
+ .getBondedDevices()
|
|
|
+ .then((List<BluetoothDevice> deviceLists) {
|
|
|
+ setState(() {
|
|
|
+ bondedDevices = deviceLists;
|
|
|
+ });
|
|
|
+ });
|
|
|
return Scaffold(
|
|
|
- appBar: AppBar(
|
|
|
- title: const Text('Second Route'),
|
|
|
- backgroundColor: Colors.blueGrey,
|
|
|
- ),
|
|
|
+ appBar: null,
|
|
|
body: Column(
|
|
|
children: [
|
|
|
- Center(
|
|
|
- child: ElevatedButton(
|
|
|
- onPressed: () {
|
|
|
- if (_isConnected && connection.isConnected) {
|
|
|
- connection.close();
|
|
|
- print('Connection Closed');
|
|
|
- _isConnected = false;
|
|
|
- }
|
|
|
- },
|
|
|
- child: const Text('Disconnect Bluetooth'),
|
|
|
- ),
|
|
|
- ),
|
|
|
- Center(
|
|
|
- child: ElevatedButton(
|
|
|
- onPressed: () async {
|
|
|
- try {
|
|
|
- connection =
|
|
|
- await BluetoothConnection.toAddress("98:D3:11:FC:39:EC");
|
|
|
- print('Connected to the device');
|
|
|
- _isConnected = true;
|
|
|
- connection.input!.listen((Uint8List data) {
|
|
|
- print(data);
|
|
|
- });
|
|
|
- } catch (ex) {
|
|
|
- print(ex);
|
|
|
- }
|
|
|
- },
|
|
|
- child: const Text('Connect Bluetooth'),
|
|
|
- ),
|
|
|
+ //Title banner
|
|
|
+ Image.asset('assets/images/scanner.png'),
|
|
|
+ //Control Buttons
|
|
|
+ Container(
|
|
|
+ alignment: Alignment.topLeft,
|
|
|
+ padding: EdgeInsetsDirectional.all(16),
|
|
|
+ child: Row(
|
|
|
+ children: [
|
|
|
+ //List Bluetooth Device Button
|
|
|
+ Container(
|
|
|
+ padding: EdgeInsets.symmetric(horizontal: 2),
|
|
|
+ child: ElevatedButton(
|
|
|
+ onPressed: () {
|
|
|
+ FlutterBluetoothSerial.instance
|
|
|
+ .getBondedDevices()
|
|
|
+ .then((List<BluetoothDevice> deviceLists) {
|
|
|
+ _statusText = "";
|
|
|
+ for (var device in deviceLists) {
|
|
|
+ print(device.address + " / " + device.name!);
|
|
|
+ setState(() {
|
|
|
+ _statusText =
|
|
|
+ "已更新藍牙裝置列表。如仍無法找到目標模組,請先到藍牙設定嘗試連接一次再載入列表。";
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ setState(() {
|
|
|
+ bondedDevices = deviceLists;
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ child: const Text('載入藍牙裝置列表'),
|
|
|
+ )),
|
|
|
+ Container(
|
|
|
+ padding: EdgeInsets.symmetric(horizontal: 2),
|
|
|
+ child:
|
|
|
+ //Connect Device Button
|
|
|
+ ElevatedButton(
|
|
|
+ style: ElevatedButton.styleFrom(
|
|
|
+ backgroundColor: (operatingDevice.deviceSelected &&
|
|
|
+ !operatingDevice.deviceConnected)
|
|
|
+ ? Colors.green
|
|
|
+ : Color.fromARGB(255, 192, 192, 192)),
|
|
|
+ onPressed: () async {
|
|
|
+ if (operatingDevice.deviceSelected &&
|
|
|
+ !operatingDevice.deviceConnected) {
|
|
|
+ //Not connected yet. Establish connection
|
|
|
+ try {
|
|
|
+ operatingDevice.connection =
|
|
|
+ await BluetoothConnection.toAddress(
|
|
|
+ operatingDevice.deviceAddr);
|
|
|
+ print('Connected to the device');
|
|
|
+ setState(() {
|
|
|
+ _statusText = "已連接到 " +
|
|
|
+ operatingDevice.deviceName +
|
|
|
+ " (" +
|
|
|
+ operatingDevice.deviceAddr +
|
|
|
+ ")";
|
|
|
+ });
|
|
|
+ operatingDevice.deviceConnected = true;
|
|
|
+ operatingDevice.connection.input!
|
|
|
+ .listen((Uint8List data) {
|
|
|
+ print(data);
|
|
|
+ });
|
|
|
+ } catch (ex) {
|
|
|
+ print(ex);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (!operatingDevice.deviceSelected) {
|
|
|
+ setState(() {
|
|
|
+ _statusText = "沒有已選擇之藍牙裝置";
|
|
|
+ });
|
|
|
+ } else if (operatingDevice.connection.isConnected) {
|
|
|
+ setState(() {
|
|
|
+ _statusText = "藍牙裝置已連接";
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ child: const Text('連接'),
|
|
|
+ )),
|
|
|
+
|
|
|
+ Container(
|
|
|
+ padding: EdgeInsets.symmetric(horizontal: 2),
|
|
|
+ child: ElevatedButton(
|
|
|
+ style: ElevatedButton.styleFrom(
|
|
|
+ backgroundColor: (operatingDevice.deviceSelected &&
|
|
|
+ operatingDevice.deviceConnected)
|
|
|
+ ? Colors.red
|
|
|
+ : Color.fromARGB(255, 192, 192, 192)),
|
|
|
+ onPressed: () {
|
|
|
+ //Disconnect BT devices
|
|
|
+ if (operatingDevice.deviceConnected &&
|
|
|
+ operatingDevice.deviceConnected) {
|
|
|
+ operatingDevice.connection.close();
|
|
|
+ print('Connection Closed');
|
|
|
+ setState(() {
|
|
|
+ _statusText = "已中斷連接";
|
|
|
+ });
|
|
|
+ operatingDevice.deviceConnected = false;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ child: const Text('斷開'),
|
|
|
+ ))
|
|
|
+ ],
|
|
|
+ )),
|
|
|
+ Container(
|
|
|
+ padding: const EdgeInsetsDirectional.all(16),
|
|
|
+ child: Text(
|
|
|
+ //Show the latest found Bluetooth addr
|
|
|
+ _statusText),
|
|
|
),
|
|
|
- Center(
|
|
|
- child: ElevatedButton(
|
|
|
- onPressed: () {
|
|
|
- FlutterBluetoothSerial.instance
|
|
|
- .getBondedDevices()
|
|
|
- .then((List<BluetoothDevice> bondedDevices) {
|
|
|
- _latestDiscoveredId = "";
|
|
|
- for (var device in bondedDevices) {
|
|
|
- print(device.address + " / " + device.name!);
|
|
|
- setState(() {
|
|
|
- _latestDiscoveredId +=
|
|
|
- "\n" + device.address + " / " + device.name!;
|
|
|
- });
|
|
|
- }
|
|
|
+ Container(
|
|
|
+ padding: const EdgeInsetsDirectional.all(16),
|
|
|
+ child: generateDiscoveredBluetoothList(bondedDevices,
|
|
|
+ (String addr, String name) {
|
|
|
+ setState(() {
|
|
|
+ operatingDevice.deviceAddr = addr;
|
|
|
+ operatingDevice.deviceName = name;
|
|
|
+ operatingDevice.deviceSelected = true;
|
|
|
+ _statusText = "已選擇裝置 " + name + "(" + addr + ")";
|
|
|
});
|
|
|
- },
|
|
|
- child: const Text('Select Bluetooth'),
|
|
|
- ),
|
|
|
- ),
|
|
|
- Text(
|
|
|
- //Show the latest found Bluetooth addr
|
|
|
- _latestDiscoveredId),
|
|
|
+ print("已選擇裝置 " + name + "(" + addr + ")");
|
|
|
+ })),
|
|
|
+
|
|
|
Center(
|
|
|
child: ElevatedButton(
|
|
|
onPressed: () {
|
|
|
- Navigator.pop(context);
|
|
|
+ Navigator.pop(context, operatingDevice);
|
|
|
},
|
|
|
- child: const Text('Go back!'),
|
|
|
+ child: const Text('返回'),
|
|
|
),
|
|
|
)
|
|
|
],
|