我有以下设置:
具有多个页面的应用:VoltagesPage
& TemperaturesPage
我将通过蓝牙串行接收一些数据,如下所示:
bluetooth_data_provider.dart
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/widgets.dart';
import 'package:flutter_bluetooth_serial/flutter_bluetooth_serial.dart';
class BluetoothDataProvider with ChangeNotifier {
String _data = '';
String get data => _data;
String _messageBuffer = '';
BluetoothConnection? _connection;
connectAndListen(String address) {
BluetoothConnection.toAddress(address).then((connection) {
print('Connected to the device');
_connection = connection;
if (_connection == null) {
return;
}
_connection!.input!.listen(_onDataReceived).onDone(() {});
}).catchError((error) {
print('Cannot connect, exception occured');
print(error);
});
}
void _onDataReceived(Uint8List data) {
String dataStr = ascii.decode(data);
_messageBuffer += dataStr;
if (dataStr.contains('\n')) {
print(_messageBuffer);
_data = _messageBuffer.substring(0, _messageBuffer.length - 1);
_messageBuffer = '';
notifyListeners();
}
}
}
这将通知所有监听 BluetoothDataProvider
对其 data
字段的更改的监听器。
现在 TemperaturesPage
对消息并不真正感兴趣,它是针对 VoltagesPage
的,反之亦然。我可以通过设备发送的前缀来确定谁应该接收消息。
电压消息可能如下所示:
V:+12.5
温度消息可能如下所示:
T:+45.6
现在,当我从两个页面观看 BluetoothDataProvider
时,小部件必须决定是否接受消息。但这可能会使小部件挂起,因为它仍然需要在调用 build
时重建小部件。
我真正想要的是这样的:
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/widgets.dart';
import 'package:flutter_bluetooth_serial/flutter_bluetooth_serial.dart';
class BluetoothDataProvider with ChangeNotifier {
String _data = '';
String get data => _data;
String _messageBuffer = '';
BluetoothConnection? _connection;
connectAndListen(String address) {
BluetoothConnection.toAddress(address).then((connection) {
print('Connected to the device');
_connection = connection;
if (_connection == null) {
return;
}
_connection!.input!.listen(_onDataReceived).onDone(() {});
}).catchError((error) {
print('Cannot connect, exception occured');
print(error);
});
}
void _onDataReceived(Uint8List data) {
String dataStr = ascii.decode(data);
_messageBuffer += dataStr;
if (dataStr.contains('\n')) {
print(_messageBuffer);
_data = _messageBuffer.substring(0, _messageBuffer.length - 1);
_messageBuffer = '';
if(_data.startsWith("T:")) {
// notify with a TemperatureProvider
} else if (_data.startsWith("V:")){
// notify with a VoltageProvider
}
}
}
}
这样,每个页面都可以监听不同的 Provider,并且只接收他们真正感兴趣的数据。
这样的场景有可能吗?
谢谢!
答案 0 :(得分:0)
我现在解决了这个问题。
在我的 main.dart 中,我将只在 BluetoothDataProvider
中创建一个 initState()
实例,并将从那里获取的上下文提供给 BluetoothDataProvider
的构造函数。
之后,我可以随意使用上下文调用不同的提供者,如下所示:
void _onDataReceived(Uint8List data) {
String dataStr = ascii.decode(data);
_messageBuffer += dataStr;
if (dataStr.contains('\n')) {
print(_messageBuffer); // here you get complete string
_data = _messageBuffer.substring(0, _messageBuffer.length - 1);
_messageBuffer = ''; //clear buffer to accept new string
var messageType = _data.substring(0, 2);
switch (messageType) {
case "V:":
context.read<CurrentReceivedMessage>().setMessage(_data);
break;
case "T:":
context.read<TemperatureReceivedMessage>().setMessage(_data);
break;
}
}
}