问题描述
我想从一个 dart 文件访问 BLE 的特征值,我正在做的是从一个活动连接设备,然后将设备信息发送到所有其他活动。但是要获得值,我必须一次又一次地为所有活动/dart 文件编写相同的代码。 例如,我在这样的活动中连接设备:
StreamBuilder<List<ScanResult>>(
stream: FlutterBlue.instance.scanResults,initialData: [],builder: (c,snapshot) => Column(
children: snapshot.data
.map(
(r) => ScanResultTile(
result: r,onTap: () => Navigator.of(context)
.push(MaterialPageRoute(builder: (context) {
r.device.connect();
print('DEVICE CONNECTED');
return BluetoothConnectedSuccess(device: r.device);
这里的 device: r.device
是我连接到 Flutter 应用程序的设备。现在,如果我想显示设备数据,我必须在每次跳转到任何屏幕/活动时初始化这些代码行:
class BluetoothConnectedSuccess extends StatefulWidget {
const BluetoothConnectedSuccess({Key key,this.device}) : super(key: key);
final BluetoothDevice device;
@override
_BluetoothConnectedSuccessstate createState() =>
_BluetoothConnectedSuccessstate();
}
class _BluetoothConnectedSuccessstate extends State<BluetoothConnectedSuccess> {
// BLE
final String SERVICE_UUID = "4fafc201-1fb5-459e-8fcc-c5c9c331914b";
final String CHaraCTERISTIC_UUID = "beb5483e-36e1-4688-b7f5-ea07361b26a8";
bool isReady;
Stream<List<int>> stream;
List<int> lastValue;
List<double> traceDust = List();
@override
void initState() {
super.initState();
isReady = false;
connectToDevice();
}
connectToDevice() async {
await widget.device.connect();
discoverServices();
}
discoverServices() async {
List<BluetoothService> services = await widget.device.discoverServices();
services.forEach((service) {
if (service.uuid.toString() == SERVICE_UUID) {
service.characteristics.forEach((characteristic) {
if (characteristic.uuid.toString() == CHaraCTERISTIC_UUID) {
characteristic.setNotifyValue(!characteristic.isnotifying);
stream = characteristic.value;
print(stream);
lastValue = characteristic.lastValue;
print(lastValue);
setState(() {
isReady = true;
});
}
});
}
});
}
_dataParser(List<int> data) {
var value = Uint8List.fromList(data);
print("stream.value: $value"); // stream.value: [33]
var hr = ByteData.sublistView(value,1);
print("Heart rate: ${hr.getUint8(0)}");
return hr.getUint8(0); // Heart rate: 33
}
为需要 BLE 数据的活动一次又一次地编写相同的代码会造成很多混乱。 有没有办法只从单个文件调用这个连接的设备,而不是在每个活动中初始化相同的代码?
这是指向我的 repo 的链接,用于查看我在使用 BLE 设备数据的每个活动/屏幕上所做的事情。 请帮助我,因为我是 Flutter 的新手。谢谢
解决方法
首先使用 Get 学习状态管理的基础知识,您可以在此处参考我的代码,每次发生的事情发生变化或更新时,它将使用特定的 Get 小部件(如 Obx 和 GetX )立即显示在 UI 中,这些小部件侦听值的变化,其中用 obs (observable) 标记。 例如:
Obx(
() => ble.isScan.value ? LinearProgressIndicator() : SizedBox(),),
这将观察 isScan 值的变化。
class BleServices extends GetxController {
FlutterBlue blue = FlutterBlue.instance;
BluetoothDevice d;
var connectedDevices = List<BluetoothDevice>().obs;
var scanResults = List<ScanResult>().obs;
var bleState = BluetoothState.off.obs;
var isScan = false.obs;
var scanRequire = false.obs;
var bluetoothServices = List<BluetoothService>().obs;
var discoveringServices = false.obs;
var characteristics = List<BluetoothCharacteristic>().obs;
@override
void onInit() async {
super.onInit();
final perb = await Permission.bluetooth.status.isGranted;
final perL = await Permission.location.status.isGranted;
if (perb && perL) {
getConnectedDevices();
} else {
await Permission.bluetooth.request();
await Permission.location.request();
}
isScanning();
state();
}
isDiscovering() async {}
getConnectedDevices() async {
final connectedDevice = await blue.connectedDevices;
connectedDevices.value = connectedDevice;
AppLogger.print('connected devices : $connectedDevice');
if (connectedDevice.length == 0) {
scanRequire.value = true;
searchDevices();
}
return connectedDevice;
}
searchDevices() {
// AppLogger.print('pppppppppppppp');
blue
.scan(timeout: Duration(seconds: 20))
.distinct()
.asBroadcastStream()
.listen((event) {
AppLogger.print(event.toString());
scanResults.addIf(!scanResults.contains(event),event);
});
Future.delayed(Duration(seconds: 20),() {
blue.stopScan();
Get.showSnackbar(GetBar(
message: 'scan is finished',));
});
}
isScanning() {
blue.isScanning.listen((event) {
AppLogger.print(event.toString());
isScan.value = event;
});
}
state() {
blue.state.listen((event) {
AppLogger.print(event.toString());
bleState.value = event;
});
}
}