Closed Flash0509 closed 9 months ago
Hi @Flash0509
I just released version 3.0.3
with some Android fixes. Let me know if it fixes your issue.
Hi, thank you for your efforts. Unfortunately it still doesn't work. In version 2.1.1 I don't get any problems with the stream when it runs through every time change:
//if (!Alarm.ringStream.hasListener) {
print("Alarm STREAMING");
Alarm.ringStream.stream.listen((_) => checkNextCompartmentTime2());
//}
But with version 3.0.3 I get this error message:
Terminal output
I/flutter ( 5524): [Alarm] [DEV] Alarm with id 42 stopped
I/flutter ( 5524): [Alarm] [DEV] Alarm with id 42 scheduled
I/flutter ( 5524): Alarm String wird übergeben
I/flutter ( 5524): Alarm STREAMING
E/flutter ( 5524): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Bad state: Stream has already been listened to.
E/flutter ( 5524): #0 _StreamController._subscribe (dart:async/stream_controller.dart:686:7)
E/flutter ( 5524): #1 _ControllerStream._createSubscription (dart:async/stream_controller.dart:836:19)
E/flutter ( 5524): #2 _StreamImpl.listen (dart:async/stream_impl.dart:471:9)
E/flutter ( 5524): #3 _HomeScreenState.startBackgroundTask (package:com.example.smartabox_app/main.dart:1092:35)
E/flutter ( 5524): <asynchronous suspension>
Hi @Flash0509
Thanks for your feedback.
The error "Bad state: Stream has already been listened to" occurs when you attempt to add more than one listener to a single-subscription stream in Dart. Single-subscription streams are designed to have only one active listener at any given time.
To ensure that there is only one listener, maintain a reference to the stream subscription and cancel it before adding a new listener. This means calling cancel() on the subscription reference whenever you're about to add a new listener. Additionally, it's crucial to cancel the subscription in the dispose method of your widget or class. This practice prevents memory leaks and ensures that your stream does not have any active listeners when the object is no longer in use.
This management of the stream subscription will prevent the error and ensure proper handling of the stream in your application.
Let me know if it helps.
Sorry for the misunderstanding. I had already made sure that there could not be a second listener. See code.
if (!Alarm.ringStream.hasListener) {
print("Alarm STREAMING");
Alarm.ringStream.stream.listen((_) => checkNextCompartmentTime2());
}
So that the stream can be accessed again and again, I have revised the code as you suggested. After the alarm is stopped, I set a subscription?.cancel();
and also took this into account when disposing the class. Unfortunately the error exists. No alarm starts properly.
Hi @Flash0509
I understand, I will investigate the issue.
In the meantime, try to call cancel() instead of your if (!Alarm.ringStream.hasListener)
, we never know. Also move your listener to a widget that will not be rebuilt. I'll keep you updated. Sorry for the inconvenience.
Hi Gautier,
Thanks for your feedback. However, I had already switched to canceling the stream. Unfortunately again without success. For verification purposes, here are the relevant excerpts from the code. By the way, there is only one alarm entry at a time, which I pass on to your plugin. This is always the next valid alarm. Only after the alarm has ended or the alarm time has been changed by the user will the void backgroundtask () be run again. If I'm not mistaken, that would make the listener call as it is now okay?
void startBackgroundTask() async {
timeFound = false;
if (alarmRun == false) {
onClose();
// nächster Alarm wird gestellt
String? einnahmezeit = fachData[nextCompartmentNumber
.toString()]?['einnahmezeit'];
if (einnahmezeit != null) {
final einnahmezeitParts = einnahmezeit.split(':');
final einnahmeTime = TimeOfDay(
hour: int.parse(einnahmezeitParts[0]),
minute: int.parse(einnahmezeitParts[1]),
);
DateTime now = DateTime.now();
DateTime scheduledTime = DateTime(
now.year,
now.month,
now.day,
einnahmeTime.hour,
einnahmeTime.minute,
);
print("Alarm Setting für nächsten Alarm werden gelesen:$scheduledTime");
final alarmSettings = AlarmSettings(
id: 42,
dateTime: scheduledTime,
assetAudioPath: 'assets/audio/beep.mp3',
loopAudio: true,
vibrate: true,
volume: 0.5,
fadeDuration: 0,
notificationTitle: 'Tabletten Erinnerung',
notificationBody: 'Einnahmezeit für Fach ' +
nextCompartmentNumber.toString() +
' erreicht. Bitte einnehmen!',
enableNotificationOnKill: true,
);
await Alarm.set(alarmSettings: alarmSettings);
print("Alarm String wird übergeben");
onInit();
}
}
}
@override
void onInit() {
print("Alarm STREAMING");
subscription ??= Alarm.ringStream.stream.listen((event) => checkNextCompartmentTime2());
}
@override
void onClose() async {
subscription?.cancel();
print('HomeController/ STREAMING: onClose');
}
Hi @Flash0509
Have you tried setting breakpoints ? Can you provide your debug console logs ? Could be very helpful to find what's causing your issue.
Hi Gautier,
Yes, of course. I'm preparing this. At the moment I'm working more with the "Print command" for debugging purposes. Please give me some time to familiarize myself with DevTools.
Here are my current observations:
After executing the command subscription ??= Alarm.ringStream.stream.listen((event) => checkNextCompartmentTime2());
Subscription has the content "Instance of '_ControllerSubscription
By the way, issue #122 sounds very similar.
Hi @Flash0509
Do you still have this issue ? Sorry I've been very busy lately.
I'm closing this issue because it looks very similar with #122. Let's discuss about this stream issue in the other thread.
okay, I agree to summarize my open issue in #122. However, I will include my last input and question for you to which you have not yet answered. ;-) I'm still interested in a solution. My project has now been delayed because of this.
Yes of course.
Version 3.0.2
Alarm plugin does not start an alarm when the alarm time is reached.
The code works with alarm version 2.1.1, but not any longer with version 3.0.2. I only adjusted the property volume in the code. In addition, I no longer start the stream call when the wake-up times change, otherwise this leads to the error: Bad state: Stream has already been listened to.
main.dart
AndroidManifest.xlm
Device info Samsung A52, android, V. 13