android - Flutter Background 任务在每天午夜处理和安排当天的通知

标签 android flutter dart notifications android-notifications

申请:任务提醒。用户创建一个任务并计划该任务何时到期。
这个包flutter_local_notification允许我在用户创建此任务时安排 future 的通知。如果我在任务到期时安排一个通知,这很好。
但是,如果用户忘记完成该任务并且该任务到期的时间已经过去(原始通知已经过去了)。我希望应用程序每天继续通知用户他们尚未完成此任务一次,直到他们打开应用程序以取消通知/将任务标记为完成。
我敢肯定,其他人一定已经创造了这样的东西,但我正在努力在网上找到明确的解决方案,所以我想我会在这里问,看看人们对最佳实践的看法。
我能想到的两个解决方案:

每日后台任务
每天运行一次的后台任务,以检查当天哪些任务到期和过期,然后在当天晚些时候的某个时间点安排通知。
系列 Activity

  • 每天 00:00 应用程序运行后台任务,检查今天到期的任务
  • 如果任务今天到期或过期。安排当天晚些时候的通知。
  • 如果应用程序从未打开,则每天都会重复检查和发送通知的过程。

  • 每天重复通知
    “星期一”到期的示例任务
    而不是每天运行后台任务。对于这个示例任务,我想我可以在星期一安排一个通知,同时也无限期地安排一个每日重复通知(星期二、星期三、星期四...)之后的每一天。然后,如果用户打开应用程序并完成任务,这些重复的通知就会被取消。如果没有,用户每天都会收到通知,直到他们收到通知。
    我认为这种方法可行,但我想避免在 future 安排这么多通知,而只安排“今天”通知。因为这个应用程序可能有很多由用户创建的任务。

    我的 Flutter 应用仅在 上运行安卓目前,但不排除 iOS .所以理想情况下是一种跨平台工作的方法。
    所有数据都存储在本地,因此我无法让后端完成数据检查和发送推送通知。
    关于这个问题的解决方案的想法?

    最佳答案

    解决方案 1:android_alarm_manager 是安排后台任务的最佳解决方案。但唯一的缺点是只支持Android。开始吧:
    像往常一样将此插件导入您的项目后,将以下内容添加到标签内的 AndroidManifest.xml 中:

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    
    接下来,在标签中,添加:
    <service
        android:name="io.flutter.plugins.androidalarmmanager.AlarmService"
        android:permission="android.permission.BIND_JOB_SERVICE"
        android:exported="false"/>
    <receiver
        android:name="io.flutter.plugins.androidalarmmanager.AlarmBroadcastReceiver"
        android:exported="false"/>
    <receiver
        android:name="io.flutter.plugins.androidalarmmanager.RebootBroadcastReceiver"
        android:enabled="false">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"></action>
        </intent-filter>
    </receiver>
    Then in Dart code add:
    
    import 'package:android_alarm_manager/android_alarm_manager.dart';
    
    void printHello() {
      final DateTime now = DateTime.now();
      final int isolateId = Isolate.current.hashCode;
      print("[$now] Hello, world! isolate=${isolateId} function='$printHello'");
    }
    
    main() async {
      final int helloAlarmID = 0;
      await AndroidAlarmManager.initialize();
      runApp(...);
      await AndroidAlarmManager.periodic(const Duration(minutes: 1), helloAlarmID, printHello);
    }
    
    如果您想每天在特定时间安排任何任务,您需要执行以下操作:
    if (Platform.isAndroid) {
       await AndroidAlarmManager.periodic(
          const Duration(hours: 24), //Do the same every 24 hours
          helloAlarmID, //Different ID for each alarm
          printHello,
          wakeup: true, //the device will be woken up when the alarm fires
          startAt: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day, 5, 0), //Start whit the specific time 5:00 am
          rescheduleOnReboot: true, //Work after reboot
       );
    }
    
    如果警报回调需要访问其他 Flutter 插件,包括警报管理器插件本身,则可能需要通知后台服务如何初始化插件,具体取决于应用程序正在使用哪个 Flutter Android 嵌入。
    这是通过给 AlarmService 一个回调来调用应用程序的 onCreate 方法来完成的。
    具体来说,它的Application类如下:
    public class Application extends FlutterApplication implements PluginRegistrantCallback {
        @Override
        public void onCreate() {
            super.onCreate();
            AlarmService.setPluginRegistrant(this);
        }
    
        @Override
        public void registerWith(PluginRegistry registry) {
            //add AndroidAlarmManagerPlugin plugin register  if you work with arlarm
            AndroidAlarmManagerPlugin.registerWith(registry.registrarFor("io.flutter.plugins.androidalarmmanager.AndroidAlarmManagerPlugin"));
        }
    }
    
    这必须反射(reflect)在应用程序的 AndroidManifest.xml 中。例如。:
    <application
            android:name=".Application"
            ...
    
    解决方案 2:Cron 是安排后台任务的另一个最佳解决方案。 Cron 以固定的时间、日期或间隔定期运行任务。但是 Jade 米的唯一缺点是一旦应用程序被杀死,cron 无法按预期在后台工作。
    一个简单的使用示例:
    import 'package:cron/cron.dart';
    
    main() {
      var cron = new Cron();
      cron.schedule(new Schedule.parse('*/3 * * * *'), () async {
        print('every three minutes');
      });
      cron.schedule(new Schedule.parse('8-11 * * * *'), () async {
        print('between every 8 and 11 minutes');
      });
    }
    
    一般如何设置 cronjob:信息
    测试 cronjob:crontab

    关于android - Flutter Background 任务在每天午夜处理和安排当天的通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64223898/

    相关文章:

    java - 导出 CSV 的格式真的很奇怪

    android - 在 Android 中导入包,但不在 IOS 中为 Flutter 应用导入包

    flutter - 使用隔离对列表进行排序

    dart - 我可以多次监听 StreamController 的流(但一次不能订阅多个)吗?

    Android GC 内部结构

    java - 连接 openfire 到 smack

    flutter - 错误 : The getter 'docs' isn't defined for the type 'Object'

    dart - Flutter:如何在同一个类的静态方法中访问成员

    dart - 在不同实例变量上引用同一对象的两个 polymer 元素(纸张输入)不起作用

    java - Android GCM 无法实例化接收器