updates
parent
ee5f90aba1
commit
992f7dd454
@ -0,0 +1,146 @@
|
|||||||
|
import 'package:diplomaticquarterapp/theme/colors.dart';
|
||||||
|
import 'package:diplomaticquarterapp/uitl/ble_utils.dart';
|
||||||
|
import 'package:diplomaticquarterapp/uitl/bluetooth_off.dart';
|
||||||
|
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
|
||||||
|
import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart';
|
||||||
|
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
|
||||||
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
|
||||||
|
class ECG_BLE extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
State<ECG_BLE> createState() => _ECG_BLEState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ECG_BLEState extends State<ECG_BLE> {
|
||||||
|
String connectionStatus = "disconnected";
|
||||||
|
|
||||||
|
BluetoothDevice currentConnectedDevice;
|
||||||
|
|
||||||
|
BluetoothCharacteristic ecgWriteCharacteristic;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
if (currentConnectedDevice != null) currentConnectedDevice.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
FlutterBluePlus.setLogLevel(LogLevel.verbose, color:false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AppScaffold(
|
||||||
|
appBarTitle: "ECG",
|
||||||
|
showNewAppBar: true,
|
||||||
|
isShowDecPage: true,
|
||||||
|
showNewAppBarTitle: true,
|
||||||
|
backgroundColor: Color(0xffF8F8F8),
|
||||||
|
body: SingleChildScrollView(
|
||||||
|
child: StreamBuilder<BluetoothAdapterState>(
|
||||||
|
stream: FlutterBluePlus.adapterState,
|
||||||
|
initialData: BluetoothAdapterState.unknown,
|
||||||
|
builder: (c, snapshot) {
|
||||||
|
final adapterState = snapshot.data;
|
||||||
|
if (adapterState == BluetoothAdapterState.on) {
|
||||||
|
return Container(
|
||||||
|
margin: EdgeInsets.only(top: 200.0, left: 50.0, right: 50.0),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Center(
|
||||||
|
child: DefaultButton(
|
||||||
|
TranslationBase.of(context).start.toUpperCase(),
|
||||||
|
() {
|
||||||
|
checkBLEPermissions();
|
||||||
|
},
|
||||||
|
color: CustomColors.green,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 50.0,
|
||||||
|
),
|
||||||
|
Text("Connection state: $connectionStatus"),
|
||||||
|
SizedBox(
|
||||||
|
height: 50.0,
|
||||||
|
),
|
||||||
|
// Text("Current Temp: $currentTempInCelsius"),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
FlutterBluePlus.stopScan();
|
||||||
|
return SizedBox(height: 300.0, child: BluetoothOffScreen(adapterState: adapterState));
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkBLEPermissions() {
|
||||||
|
[Permission.location, Permission.storage, Permission.bluetooth, Permission.bluetoothConnect, Permission.bluetoothScan].request().then((status) {
|
||||||
|
startBLEConnection();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void startBLEConnection() {
|
||||||
|
if (FlutterBluePlus.isScanningNow == false) {
|
||||||
|
setState(() {
|
||||||
|
connectionStatus = "Connecting...";
|
||||||
|
});
|
||||||
|
|
||||||
|
FlutterBluePlus.startScan(timeout: const Duration(seconds: 5), androidUsesFineLocation: false).then((value) {
|
||||||
|
List<ScanResult> blueToothDevices = value;
|
||||||
|
blueToothDevices.forEach((element) async {
|
||||||
|
if (element.device.localName.isNotEmpty) {
|
||||||
|
if (element.device.localName.toLowerCase() == "pm101897") {
|
||||||
|
element.device.connectionState.listen((BluetoothConnectionState state) async {
|
||||||
|
if(mounted) {
|
||||||
|
setState(() {
|
||||||
|
connectionStatus = state.toString();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (state == BluetoothConnectionState.disconnected) {
|
||||||
|
// typically, start a periodic timer that tries to periodically reconnect.
|
||||||
|
// Note: you must always re-discover services after disconnection!
|
||||||
|
}
|
||||||
|
if (state == BluetoothConnectionState.connected) {
|
||||||
|
currentConnectedDevice = element.device;
|
||||||
|
List<BluetoothService> services = await element.device.discoverServices();
|
||||||
|
services.forEach((service) {
|
||||||
|
if (service.serviceUuid.toString().toLowerCase() == BLEUtils.ECG_SERVICE) {
|
||||||
|
print(service.serviceUuid);
|
||||||
|
service.characteristics.forEach((characteristic) async {
|
||||||
|
if (characteristic.characteristicUuid.toString().toLowerCase() == BLEUtils.ECG_READ_CHARACTERISTIC) {
|
||||||
|
print(characteristic.characteristicUuid);
|
||||||
|
characteristic.onValueReceived.listen((event) {
|
||||||
|
print("onValueReceived Stream");
|
||||||
|
print(event);
|
||||||
|
});
|
||||||
|
await characteristic.setNotifyValue(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (characteristic.characteristicUuid.toString().toLowerCase() == BLEUtils.ECG_WRITE_CHARACTERISTIC) {
|
||||||
|
print(characteristic.characteristicUuid);
|
||||||
|
ecgWriteCharacteristic = characteristic;
|
||||||
|
ecgWriteCharacteristic.write([0x90], allowLongWrite: true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
await element.device.connect(timeout: Duration(seconds: 35));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,205 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:diplomaticquarterapp/theme/colors.dart';
|
||||||
|
import 'package:diplomaticquarterapp/uitl/ble_utils.dart';
|
||||||
|
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
|
||||||
|
import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart';
|
||||||
|
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
|
||||||
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
|
||||||
|
class SpirometerBLE extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
State<SpirometerBLE> createState() => _SpirometerBLEState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SpirometerBLEState extends State<SpirometerBLE> {
|
||||||
|
String connectionStatus = "disconnected";
|
||||||
|
BluetoothDevice currentConnectedDevice;
|
||||||
|
|
||||||
|
Timer _timer;
|
||||||
|
|
||||||
|
Timer _timerRead;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
if (currentConnectedDevice != null) currentConnectedDevice.disconnect();
|
||||||
|
if (_timer != null && _timer.isActive) _timer.cancel();
|
||||||
|
if (_timerRead != null && _timerRead.isActive) _timerRead.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AppScaffold(
|
||||||
|
appBarTitle: TranslationBase.of(context).spirometer,
|
||||||
|
showNewAppBar: true,
|
||||||
|
isShowDecPage: true,
|
||||||
|
showNewAppBarTitle: true,
|
||||||
|
backgroundColor: Color(0xffF8F8F8),
|
||||||
|
body: SingleChildScrollView(
|
||||||
|
child: StreamBuilder<BluetoothAdapterState>(
|
||||||
|
stream: FlutterBluePlus.adapterState,
|
||||||
|
initialData: BluetoothAdapterState.unknown,
|
||||||
|
builder: (c, snapshot) {
|
||||||
|
final adapterState = snapshot.data;
|
||||||
|
if (adapterState == BluetoothAdapterState.on) {
|
||||||
|
return Container(
|
||||||
|
margin: EdgeInsets.only(top: 200.0, left: 50.0, right: 50.0),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Center(
|
||||||
|
child: DefaultButton(
|
||||||
|
TranslationBase.of(context).start.toUpperCase(),
|
||||||
|
() {
|
||||||
|
checkBLEPermissions();
|
||||||
|
},
|
||||||
|
color: CustomColors.green,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 50.0,
|
||||||
|
),
|
||||||
|
Text("Connection state: $connectionStatus"),
|
||||||
|
SizedBox(
|
||||||
|
height: 50.0,
|
||||||
|
),
|
||||||
|
// Text("Current Temp: $currentTempInCelsius"),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
FlutterBluePlus.stopScan();
|
||||||
|
return SizedBox(height: 300.0, child: BluetoothOffScreen(adapterState: adapterState));
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkBLEPermissions() {
|
||||||
|
[Permission.location, Permission.storage, Permission.bluetooth, Permission.bluetoothConnect, Permission.bluetoothScan].request().then((status) {
|
||||||
|
startBLEConnection();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void startBLEConnection() {
|
||||||
|
if (FlutterBluePlus.isScanningNow == false) {
|
||||||
|
setState(() {
|
||||||
|
connectionStatus = "Connecting...";
|
||||||
|
});
|
||||||
|
|
||||||
|
FlutterBluePlus.startScan(timeout: const Duration(seconds: 5), androidUsesFineLocation: false).then((value) {
|
||||||
|
List<ScanResult> blueToothDevices = value;
|
||||||
|
blueToothDevices.forEach((element) async {
|
||||||
|
if (element.device.localName.isNotEmpty) {
|
||||||
|
if (element.device.localName.toLowerCase() == "ble-msa") {
|
||||||
|
element.device.connectionState.listen((BluetoothConnectionState state) async {
|
||||||
|
setState(() {
|
||||||
|
connectionStatus = state.toString();
|
||||||
|
});
|
||||||
|
if (state == BluetoothConnectionState.disconnected) {
|
||||||
|
// typically, start a periodic timer that tries to periodically reconnect.
|
||||||
|
// Note: you must always re-discover services after disconnection!
|
||||||
|
if (_timer != null && _timer.isActive) _timer.cancel();
|
||||||
|
if (_timerRead != null && _timerRead.isActive) _timerRead.cancel();
|
||||||
|
}
|
||||||
|
if (state == BluetoothConnectionState.connected) {
|
||||||
|
currentConnectedDevice = element.device;
|
||||||
|
|
||||||
|
List<int> BLEToMSAWriteCharacters = [];
|
||||||
|
BLEToMSAWriteCharacters.add(int.parse("5506", radix: 16));
|
||||||
|
|
||||||
|
List<BluetoothService> services = await element.device.discoverServices();
|
||||||
|
services.forEach((service) {
|
||||||
|
if (service.serviceUuid.toString().toLowerCase() == BLEUtils.BLE_TO_MSA100_SERVICE) {
|
||||||
|
print(service.serviceUuid);
|
||||||
|
service.characteristics.forEach((characteristic) async {
|
||||||
|
if (characteristic.characteristicUuid.toString().toLowerCase() == BLEUtils.BLE_TO_MSA100_CHARACTERISTIC) {
|
||||||
|
print(characteristic.characteristicUuid);
|
||||||
|
_timer = Timer.periodic(Duration(seconds: 2), (Timer timer) {
|
||||||
|
characteristic.write(BLEToMSAWriteCharacters).then((value) {
|
||||||
|
print("Characteristic response:");
|
||||||
|
}).catchError((err) {});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (characteristic.characteristicUuid.toString().toLowerCase() == BLEUtils.MSA100_TO_BLE_CHARACTERISTIC) {
|
||||||
|
print(characteristic.characteristicUuid);
|
||||||
|
_timerRead = Timer.periodic(Duration(seconds: 2), (Timer timer) {
|
||||||
|
characteristic.read().then((value) {
|
||||||
|
print("Characteristic Read value: ");
|
||||||
|
print(value);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// characteristic.onValueReceived.listen((event) {
|
||||||
|
// print("onValueReceived Stream");
|
||||||
|
// print(event);
|
||||||
|
// setState(() {
|
||||||
|
// currentTempInCelsius = convertIntListToHex(event);
|
||||||
|
// String currentTempInFahrenheit = ((num.parse(currentTempInCelsius) * 1.8) + 32).toStringAsFixed(1);
|
||||||
|
// currentTempInCelsius = currentTempInCelsius + "\u2103" + " / " + currentTempInFahrenheit + "\u2109";
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
// await characteristic.setNotifyValue(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
await element.device.connect(timeout: Duration(seconds: 35));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BluetoothOffScreen extends StatelessWidget {
|
||||||
|
const BluetoothOffScreen({Key key, this.adapterState}) : super(key: key);
|
||||||
|
|
||||||
|
final BluetoothAdapterState adapterState;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ScaffoldMessenger(
|
||||||
|
child: Scaffold(
|
||||||
|
backgroundColor: Colors.lightBlue,
|
||||||
|
body: Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: <Widget>[
|
||||||
|
const Icon(
|
||||||
|
Icons.bluetooth_disabled,
|
||||||
|
size: 200.0,
|
||||||
|
color: Colors.white54,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'Bluetooth Adapter is ${adapterState != null ? adapterState.toString().split(".").last + ", Please turn on your bluetooth to continue." : 'not available'}.',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: Theme.of(context).primaryTextTheme.titleSmall?.copyWith(color: Colors.white),
|
||||||
|
),
|
||||||
|
if (Platform.isAndroid)
|
||||||
|
ElevatedButton(
|
||||||
|
child: const Text('TURN ON'),
|
||||||
|
onPressed: () async {
|
||||||
|
try {
|
||||||
|
if (Platform.isAndroid) {
|
||||||
|
await FlutterBluePlus.turnOn();
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
|
||||||
|
|
||||||
|
class BluetoothOffScreen extends StatelessWidget {
|
||||||
|
const BluetoothOffScreen({Key key, this.adapterState}) : super(key: key);
|
||||||
|
|
||||||
|
final BluetoothAdapterState adapterState;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ScaffoldMessenger(
|
||||||
|
child: Scaffold(
|
||||||
|
backgroundColor: Colors.lightBlue,
|
||||||
|
body: Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: <Widget>[
|
||||||
|
const Icon(
|
||||||
|
Icons.bluetooth_disabled,
|
||||||
|
size: 200.0,
|
||||||
|
color: Colors.white54,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'Bluetooth Adapter is ${adapterState != null ? adapterState.toString().split(".").last + ", Please turn on your bluetooth to continue." : 'not available'}.',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: Theme.of(context).primaryTextTheme.titleSmall?.copyWith(color: Colors.white),
|
||||||
|
),
|
||||||
|
if (Platform.isAndroid)
|
||||||
|
ElevatedButton(
|
||||||
|
child: const Text('TURN ON'),
|
||||||
|
onPressed: () async {
|
||||||
|
try {
|
||||||
|
if (Platform.isAndroid) {
|
||||||
|
await FlutterBluePlus.turnOn();
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue