颤振如何将消息传递到Android AlarmManager创建的隔离

时间:2020-07-04 06:04:47

标签: android flutter alarmmanager dart-isolates

我正在使用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));
  }

因此,闹钟设置完美,并且会在设置的准确时间响起。但是,当我想停止播放音乐时,无法停止播放。因此,我必须使用oneShot中的另一个AlarmManager才能访问隔离并停止音乐,如上面的代码所示。这样可以停止播放音乐,但是仅需3秒钟以上即可停止播放音乐。

我的问题是,一旦按下停止按钮,如何使AlarmManger立即停止音乐。

谢谢, 杰克

编辑:删除了保留用于测试的行。

1 个答案:

答案 0 :(得分:0)

因此,在网上搜索后,我终于找到了一种方法,可以在按下后立即停止播放器。

AlarmManger创建隔离时,您必须在callback的{​​{1}}函数内创建一个接收端口。在我的情况下是AlarmManger

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函数中提供的任何操作,在我的情况下是停止播放器。

希望这会有所帮助。