Sure! Here's the fixed message to ask for help on Stack Overflow:
I am working with flutter_blue_plus
and flutter_foreground_task
packages.
I have a Bluetooth handler class called BluetoothTaskHandler
, which extends TaskHandler
. Here's the code:
class BluetoothTaskHandler extends TaskHandler {
SendPort? _sendPort;
@override
Future<void> onStart(DateTime timestamp, SendPort? sendPort) async {
_sendPort = sendPort;
// Here, I perform the setup for the Bluetooth device, services, characteristics, and listeners.
}
// This is the listener specific to a characteristic.
void onBreathEcgValueReceived(List<int> event) {
// Send data to the main isolate.
EcgBrtValueDto? result = bluetoothBreathEcgInterpreter.getEcgBrt(Uint8List.fromList(event));
if (result != null) {
var brt = result.brt;
var ecg = result.ecg;
logger.info("@onBreathEcgValueReceived ecg ${ecg.toString()}");
logger.info("@onBreathEcgValueReceived brt ${brt.toString()}");
if (_sendPort != null) {
FlutterForegroundTask.isAppOnForeground.then((isAppOnForeground) {
if (isAppOnForeground) {
_sendPort?.send(json.encode(result.toJson()));
}
});
}
}
}
}
In my widget, I have the following code (only the State
part is relevant). There is an important comment:
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) async {
if (await FlutterForegroundTask.isRunningService) {
setUpPortStream();
}
});
WidgetsBinding.instance.addObserver(this);
}
setUpPortStream() {
// Type: ReceivePort?
final newReceivePort = FlutterForegroundTask.receivePort;
if (newReceivePort == null) {
logger.warn("@setUpPortStream no receive port");
return;
}
/*** IMPORTANT: if I uncomment this, I see the data coming ***/
/*newReceivePort.listen((message) {
logger.info("Received $message");
});*/
return;
// [..] Build stuff [..]
StreamBuilder<dynamic>(
// Already tried: stream: newReceivePort.asBroadcastStream(),
stream: newReceivePort.asBroadcastStream(),
builder: (context, snapshot) {
List<Widget> children;
if (!snapshot.hasData) {
logger.debug("@showBatteryStatus snapshot has no data in it.");
children = <Widget>[const Text('no data.')];
}
// [...]
}
);
}
The issue I'm facing is that it always displays "No data" in the StreamBuilder
. I also tried converting the subscription to a stream using the convertSubscriptionToStream
method, but without success.
Additionally, after initializing the foreground task, this is the top-level callback:
// The callback function should always be a top-level function.
@pragma('vm:entry-point')
void startCallback() {
// The setTaskHandler function must be called to handle the task in the background.
FlutterForegroundTask.setTaskHandler(BluetoothTaskHandler());
}
I would appreciate any help or suggestions on why I'm not receiving data in the StreamBuilder
. Thank you!
Stop creating the stream as the stream: parameter of the StreamBuilder. Watch this for why and how to fix: https://youtu.be/sqE-J8YJnpg