APPLICATION: Task reminders. The user creates a task and schedules when this task is due.
This package flutter_local_notification allows me to schedule a future notification to the user when they create this task. Which is fine if I schedule one notification for when the task is due.
However, if the user forgets to complete that task and the day has now past when the task was due (with the original notification been and gone). I would like the app to continue to notify the user that they haven't completed this task yet once every day, until they open the app to cancel the notification/mark the task as complete.
I'm certain that others must have already created something like this, but I'm struggling to find clear solutions online so thought I would ask here and see peoples opinions on what would be best practice.
Two solutions I can think of:
A background task to run once a day to check what tasks are due and overdue for that current day and then schedule a notification for some point later during that day.
Series of events
Example Task due on "Monday"
Instead of having a background task run everyday. For this example task I'm thinking I could schedule a notification on the Monday, and at the same time also schedule a daily repeating notification for every day after (Tuesdays, Wednesday, Thursday...) indefinitely. Then if the user opens the app and completes the task, these repeating notifications are cancelled. If not, the user gets notified every day until they do.
I think this method would work, but I want to avoid scheduling so many notifications in the future and only have "todays" notifications scheduled. As this app could potentially have lots of tasks created by the user.
My flutter app is only running only on Android at the moment, but I don't want to rule out iOS. So ideally a method which works cross-platform.
All the data is stored locally, so I can't have a backend completing the data checks and sending push notifications.
Thoughts on the solutions to this problem?
APPLICATION: Task reminders. The user creates a task and schedules when this task is due. This package flutter_local_notification allows me to schedule a future notification to the user when they create this task. Which is fine if I schedule one notification for when the task is due.
WorkManager provides an easy-to-use API where we can define a background job that should run once, or periodically, apply multiple constraints like for example if a task needs an internet connection, or if the battery should be fully charged, and much more. It is a cross-platform plugin for displaying local notifications in a flutter application.
A background task to run once a day to check what tasks are due and overdue for that current day and then schedule a notification for some point later during that day. At 00:00 every day the app runs a background task checking what tasks are due today If a task is due today, or is overdue. Schedule notification for later that day.
You can also refer to a medium article for the same. SOLUTION: Cron is another best solution to schedule background tasks. Cron runs tasks periodically at fixed times, dates, or intervals. But the only disadvantage of corn is once the app kills, the cron not working in the background as expected.
SOLUTION 1: android_alarm_manager is the best solution to schedule background tasks. But the only disadvantage is only support Android. Let's start:
After importing this plugin to your project as usual, add the following to your AndroidManifest.xml within the tags:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
Next, within the tags, add:
<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 you want to schedule any task every day at a specific time, you need to do something like this:
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
);
}
If alarm callbacks will need access to other Flutter plugins, including the alarm manager plugin itself, it may be necessary to inform the background service how to initialize plugins depending on which Flutter Android embedding the application is using.
This is done by giving the AlarmService a callback to call the application's onCreate method.
In particular, its Application class is as follows:
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"));
}
}
Which must be reflected in the application's AndroidManifest.xml. E.g.:
<application
android:name=".Application"
...
SOLUTION 2: Cron is another best solution to schedule background tasks. Cron run tasks periodically at fixed times, dates or intervals. But the onliy disadvantage of corn is once the app kill, cron not working in background as expected.
A simple usage example:
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');
});
}
How to setup a cronjob in general: information
Test cronjob: crontab
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With