Flutter 如何将消息传递给 Android AlarmManager 创建的隔离区
Flutter how to pass messages to the isolate created by Android AlarmManager
我正在使用 Android AlarmManger
在特定日期和时间设置 oneShotAt
闹钟。一旦闹钟被激活,我就在 FlutterRingtonePlayer
的帮助下播放循环声音。
class _MyHomePageState extends State<MyHomePage> {
TimeOfDay _time = TimeOfDay.now();
DateTime _date = DateTime.now();
final int helloAlarmID = 0;
static playLocalAsset() {
final DateTime now = DateTime.now();
final int isolateId = Isolate.current.hashCode;
print("[$now] Hello, world! isolate=${isolateId}");
FlutterRingtonePlayer.playAlarm(looping: true);
}
static stopLocalAsset() {
print("TEST");
FlutterRingtonePlayer.stop();
}
void stopMusic() async {
AndroidAlarmManager.oneShot(Duration(seconds: 0), helloAlarmID, stopLocalAsset);
}
//Date and Time Picking
Future<Null> selectTime(BuildContext context) async {
await selectDate(context);
_time = await showTimePicker(context: context, initialTime: _time);
_date = DateTime(_date.year, _date.month, _date.day, _time.hour, _time.minute);
print(_date);
await AndroidAlarmManager.oneShotAt(_date, helloAlarmID, playLocalAsset); //ALARM SET HERE
}
Future<Null> selectDate(BuildContext context) async {
_date = await showDatePicker(context: context, initialDate: _date, firstDate: _date, lastDate: DateTime(2222));
}
所以闹钟设置得很完美,它会在准确的时间响起。但是,当我想停止音乐时,却无法停止。所以我不得不使用 AlarmManager
的另一个 oneShot
来访问隔离并停止音乐,如上面的代码所示。这样就停止了音乐,但是光是停止音乐就需要3秒多的时间。
我的问题是,如何让 AlarmManger
在按下停止按钮后立即停止播放音乐。
谢谢,
杰克
编辑:删除了保留用于测试的行。
所以在网上搜索后,我终于找到了一种在按下后立即停止播放器的方法。
由于AlarmManger
创建了一个隔离,你必须在AlarmManger
的callback
函数中创建一个接收端口。在我的例子中是static playLocalAsset()
static playLocalAsset() {
ReceivePort rcPort = new ReceivePort();
IsolateNameServer.registerPortWithName(rcPort.sendPort, portName);
rcPort.listen((v) {
FlutterRingtonePlayer.stop();
});
final DateTime now = DateTime.now();
final int isolateId = Isolate.current.hashCode;
print("[$now] Hello, world! isolate=${isolateId}");
FlutterRingtonePlayer.playAlarm(looping: true);
}
在所有函数之外创建一个端口名(比如一个全局变量),如
const String portName = "ConnectingIsolate";
现在在您的停止按钮函数中创建一个 SendPort
,它将发送到您已在全局声明的端口名。在我的例子中,最后的 stopLocalAsset()
看起来像
void stopMusic() {
SendPort sendPort = IsolateNameServer.lookupPortByName(portName);
sendPort.send("Abcd");
}
所以,基本上,当您通过 SendPort
发送内容时,接收端口(处于隔离状态)将监听并执行您在 rcport.listen
函数中提供的任何操作,这在我的案例是停止播放器。
希望这对您有所帮助。
我正在使用 Android AlarmManger
在特定日期和时间设置 oneShotAt
闹钟。一旦闹钟被激活,我就在 FlutterRingtonePlayer
的帮助下播放循环声音。
class _MyHomePageState extends State<MyHomePage> {
TimeOfDay _time = TimeOfDay.now();
DateTime _date = DateTime.now();
final int helloAlarmID = 0;
static playLocalAsset() {
final DateTime now = DateTime.now();
final int isolateId = Isolate.current.hashCode;
print("[$now] Hello, world! isolate=${isolateId}");
FlutterRingtonePlayer.playAlarm(looping: true);
}
static stopLocalAsset() {
print("TEST");
FlutterRingtonePlayer.stop();
}
void stopMusic() async {
AndroidAlarmManager.oneShot(Duration(seconds: 0), helloAlarmID, stopLocalAsset);
}
//Date and Time Picking
Future<Null> selectTime(BuildContext context) async {
await selectDate(context);
_time = await showTimePicker(context: context, initialTime: _time);
_date = DateTime(_date.year, _date.month, _date.day, _time.hour, _time.minute);
print(_date);
await AndroidAlarmManager.oneShotAt(_date, helloAlarmID, playLocalAsset); //ALARM SET HERE
}
Future<Null> selectDate(BuildContext context) async {
_date = await showDatePicker(context: context, initialDate: _date, firstDate: _date, lastDate: DateTime(2222));
}
所以闹钟设置得很完美,它会在准确的时间响起。但是,当我想停止音乐时,却无法停止。所以我不得不使用 AlarmManager
的另一个 oneShot
来访问隔离并停止音乐,如上面的代码所示。这样就停止了音乐,但是光是停止音乐就需要3秒多的时间。
我的问题是,如何让 AlarmManger
在按下停止按钮后立即停止播放音乐。
谢谢, 杰克
编辑:删除了保留用于测试的行。
所以在网上搜索后,我终于找到了一种在按下后立即停止播放器的方法。
由于AlarmManger
创建了一个隔离,你必须在AlarmManger
的callback
函数中创建一个接收端口。在我的例子中是static playLocalAsset()
static playLocalAsset() {
ReceivePort rcPort = new ReceivePort();
IsolateNameServer.registerPortWithName(rcPort.sendPort, portName);
rcPort.listen((v) {
FlutterRingtonePlayer.stop();
});
final DateTime now = DateTime.now();
final int isolateId = Isolate.current.hashCode;
print("[$now] Hello, world! isolate=${isolateId}");
FlutterRingtonePlayer.playAlarm(looping: true);
}
在所有函数之外创建一个端口名(比如一个全局变量),如
const String portName = "ConnectingIsolate";
现在在您的停止按钮函数中创建一个 SendPort
,它将发送到您已在全局声明的端口名。在我的例子中,最后的 stopLocalAsset()
看起来像
void stopMusic() {
SendPort sendPort = IsolateNameServer.lookupPortByName(portName);
sendPort.send("Abcd");
}
所以,基本上,当您通过 SendPort
发送内容时,接收端口(处于隔离状态)将监听并执行您在 rcport.listen
函数中提供的任何操作,这在我的案例是停止播放器。
希望这对您有所帮助。