I'm currently writing an alarm clock app in Flutter and need to be able to start playing a custom sound at a specific time, even without the app currently running. I've already been able to achieve this with the following code (Using Android Alarm Manager Plus Flutter Package):
onTap() async {
await AndroidAlarmManager.oneShot(
const Duration(seconds: 5),
0,
playRingtone,
exact: true,
wakeup: true,
);
}
Future<void> playRingtone() async {
await FlutterRingtonePlayer.play(
fromAsset: "assets/song.mp3",
looping: true, // Android only - API >= 28
volume: 0.1, // Android only - API >= 28
asAlarm: true, // Android only - all APIs
);
}
For test purposes I'm firing an alarm 5 seconds from the point in time where the associated button is pressed. Now, here is where I run into a problem: It turns out to be rather diffcult to stop playing that same sound.
The code that is supposed to stop the sound from playing
FlutterRingtonePlayer.stop();
AndroidAlarmManager.cancel(0);
is not doing much of anything. I run that code from another button tap somewhere else in the app. I suppose things are not working out because FlutterRingtonePlayer starts playing from an isolate/thread inside AlarmManager and so even if I kill the AlarmManager isolate/thread, the FlutterRingtonePlayer isolate (inside AlarmManager isolate) still keeps running. Not sure though..
I just found the answer, which is actually quite simple: One needs to start another oneShot with AlarmManager using the same ID as before and simply stop the ringtone from there:
await AndroidAlarmManager.oneShot(
const Duration(seconds: 0),
0, //This ID has to be the same as above
stopRingtone,
exact: true,
wakeup: true,
);
Future<void> stopRingtone() async {
await FlutterRingtonePlayer.stop();
}