Copy old project - initial state
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter_bluetooth_serial/flutter_bluetooth_serial.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:nmea/nmea.dart';
|
||||
import 'package:terepi_seged/gnss_sentences/gngga.dart';
|
||||
|
||||
class BluetoothTestViewController extends GetxController {
|
||||
Rx<BluetoothState> bluetoothState = BluetoothState.UNKNOWN.obs;
|
||||
RxList<BluetoothDevice> devices = RxList<BluetoothDevice>([]);
|
||||
Rx<BluetoothDevice>? selectedDevice;
|
||||
final NmeaDecoder nmeaDecoder = NmeaDecoder();
|
||||
|
||||
BluetoothConnection? connection;
|
||||
StreamSubscription<BluetoothDiscoveryResult>? _bluetoothDiscoveryStream;
|
||||
RxList<BluetoothDiscoveryResult> bluetoothDiscoveryResults =
|
||||
RxList<BluetoothDiscoveryResult>.empty(growable: true);
|
||||
|
||||
// bool get isConnected => connection != null && connection!.isConnected;
|
||||
bool isConnected = false;
|
||||
int count = 0;
|
||||
String _messageBuffer = '';
|
||||
bool hasGpsData = false;
|
||||
DateTime lastGpsRefreshTime = DateTime.now();
|
||||
RxString utcOfPositionFix = "".obs;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
|
||||
print("Call BluetoothTestController.OnInit");
|
||||
|
||||
FlutterBluetoothSerial.instance.state.then((state) {
|
||||
bluetoothState.value = state;
|
||||
if (bluetoothState.value.isEnabled) {
|
||||
//_listBoundedDevices();
|
||||
_startDiscovery();
|
||||
}
|
||||
});
|
||||
nmeaDecoder.registerTalkerSentence("GGA", (line) => Gngga(raw: line));
|
||||
|
||||
//Loading, Success, Error handle with 1 line of code
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
super.onClose();
|
||||
FlutterBluetoothSerial.instance.setPairingRequestHandler(null);
|
||||
if (isConnected) {
|
||||
connection?.close();
|
||||
// connection = null;
|
||||
print("BluetoothTestController dispose ....");
|
||||
}
|
||||
}
|
||||
|
||||
_listBoundedDevices() {
|
||||
FlutterBluetoothSerial.instance
|
||||
.getBondedDevices()
|
||||
.then((List<BluetoothDevice> boundedDevices) {
|
||||
devices.value = boundedDevices;
|
||||
devices.refresh();
|
||||
});
|
||||
}
|
||||
|
||||
void setSelectedDevice(BluetoothDevice device) {
|
||||
selectedDevice = Rx<BluetoothDevice>(device);
|
||||
|
||||
if (!isConnected) {
|
||||
BluetoothConnection.toAddress(selectedDevice?.value.address)
|
||||
.then((value) {
|
||||
connection = value;
|
||||
isConnected = true;
|
||||
print("Bleutooth device connected .... ${connection!.isConnected}");
|
||||
|
||||
connection!.input!.listen(_onDataReceived);
|
||||
});
|
||||
|
||||
// connection!.input!.listen((data) {
|
||||
// print("Data -> $data");
|
||||
// });
|
||||
}
|
||||
}
|
||||
|
||||
void _startDiscovery() {
|
||||
_bluetoothDiscoveryStream =
|
||||
FlutterBluetoothSerial.instance.startDiscovery().listen((event) {
|
||||
final existingIndex = bluetoothDiscoveryResults.indexWhere(
|
||||
(element) => element.device.address == event.device.address);
|
||||
if (existingIndex > 0) {
|
||||
bluetoothDiscoveryResults[existingIndex] = event;
|
||||
update();
|
||||
} else {
|
||||
bluetoothDiscoveryResults.add(event);
|
||||
update();
|
||||
}
|
||||
});
|
||||
|
||||
_bluetoothDiscoveryStream!.onDone(() {});
|
||||
}
|
||||
|
||||
void _onDataReceived(Uint8List data) {
|
||||
// Allocate buffer for parsed data
|
||||
int backspacesCounter = 0;
|
||||
String sentence = '';
|
||||
|
||||
// print("Data: $data");
|
||||
|
||||
for (var byte in data) {
|
||||
if (byte == 8 || byte == 127) {
|
||||
backspacesCounter++;
|
||||
}
|
||||
}
|
||||
Uint8List buffer = Uint8List(data.length - backspacesCounter);
|
||||
int bufferIndex = buffer.length;
|
||||
|
||||
// Apply backspace control character
|
||||
backspacesCounter = 0;
|
||||
for (int i = data.length - 1; i >= 0; i--) {
|
||||
if (data[i] == 8 || data[i] == 127) {
|
||||
backspacesCounter++;
|
||||
} else {
|
||||
if (backspacesCounter > 0) {
|
||||
backspacesCounter--;
|
||||
} else {
|
||||
buffer[--bufferIndex] = data[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create message if there is new line character
|
||||
String dataString = String.fromCharCodes(buffer);
|
||||
int index = buffer.indexOf(13);
|
||||
if (~index != 0) {
|
||||
sentence = backspacesCounter > 0
|
||||
? _messageBuffer.substring(
|
||||
0, _messageBuffer.length - backspacesCounter)
|
||||
: _messageBuffer + dataString.substring(0, index);
|
||||
_messageBuffer = dataString.substring(index);
|
||||
} else {
|
||||
_messageBuffer = (backspacesCounter > 0
|
||||
? _messageBuffer.substring(
|
||||
0, _messageBuffer.length - backspacesCounter)
|
||||
: _messageBuffer + dataString);
|
||||
}
|
||||
|
||||
count++;
|
||||
// print("Message ($count): $sentence");
|
||||
_processGnssMessage(sentence);
|
||||
}
|
||||
|
||||
void _processGnssMessage(String message) {
|
||||
LineSplitter lineSplitter = const LineSplitter();
|
||||
List<String> lines = lineSplitter.convert(message);
|
||||
|
||||
if (lines.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (String line in lines) {
|
||||
if (line.trim().isEmpty) {
|
||||
continue;
|
||||
}
|
||||
if (line.startsWith("\$GNGGA")) {
|
||||
final sentence = nmeaDecoder.decode(line);
|
||||
if (sentence!.valid && sentence is Gngga) {
|
||||
hasGpsData = sentence.gpsQualityIndicator > 0;
|
||||
if (hasGpsData) {
|
||||
if (DateTime.now().difference(lastGpsRefreshTime).inSeconds >= 4) {
|
||||
lastGpsRefreshTime = DateTime.now();
|
||||
utcOfPositionFix.value = sentence.utcOfPositionFix;
|
||||
}
|
||||
print("Last update: $utcOfPositionFix");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bluetooth_serial/flutter_bluetooth_serial.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:terepi_seged/models/bluetooth_device_list_entry.dart';
|
||||
import 'package:terepi_seged/pages/bleutooth/presentation/controllers/bluetooth_controller.dart';
|
||||
|
||||
class BluetoothTestView extends GetView<BluetoothTestViewController> {
|
||||
const BluetoothTestView({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
child: Scaffold(
|
||||
extendBody: true,
|
||||
backgroundColor: Colors.black.withOpacity(0.05),
|
||||
appBar: AppBar(
|
||||
elevation: 0.0,
|
||||
title: const Text('BluetoothTest'),
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.arrow_back_ios),
|
||||
color: Colors.white,
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
},
|
||||
),
|
||||
),
|
||||
body: Column(children: [
|
||||
const Center(
|
||||
child: Text("BluetoothTestView"),
|
||||
),
|
||||
ListTile(
|
||||
title: const Text(
|
||||
'Bluetooth status',
|
||||
),
|
||||
subtitle: Obx(() => Text("${controller.bluetoothState}")),
|
||||
trailing: ElevatedButton(
|
||||
child: const Text('Settings'),
|
||||
onPressed: () {
|
||||
FlutterBluetoothSerial.instance.openSettings();
|
||||
},
|
||||
),
|
||||
),
|
||||
Obx(() => Text(
|
||||
"${controller.bluetoothState}",
|
||||
style: TextStyle(
|
||||
color: controller.bluetoothState.value.isEnabled
|
||||
? Colors.green
|
||||
: Colors.red),
|
||||
)),
|
||||
Obx(() => Text("Last update: ${controller.utcOfPositionFix}",
|
||||
style: const TextStyle(
|
||||
color: Colors.blue, fontWeight: FontWeight.bold))),
|
||||
Expanded(
|
||||
child: Obx(
|
||||
() => ListView(
|
||||
children: controller.bluetoothDiscoveryResults
|
||||
.map((device) => BluetoothDeviceListEntry(
|
||||
device: device.device,
|
||||
enabled: true,
|
||||
onTap: () {
|
||||
print("Device: ${device.device.address}");
|
||||
controller.setSelectedDevice(device.device);
|
||||
},
|
||||
))
|
||||
.toList()),
|
||||
))
|
||||
])));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user