I have a provider where I have a list of tasks, it happens that, I want to implement a way in which after a specific time, I would like to remove a task from the list.
class TaskProvider extends ChangeNotifier {
final List<TaskModel> _tasks = [];
List<TaskModel> get tasks => _tasks;
final String _tasksKey = "tasks";
Future<void> addTask({
required String task,
required DateTime scheduledTime,
required TaskStatus status,
}) async {
scheduleTaskManager(task, scheduledTime);
_tasks.add(
TaskModel(task: task, limitDateTime: scheduledTime, status: status));
notifyListeners();
}
Future<void> clearTasks() async {
dev.log("Tasks deleted!");
tasks.clear();
notifyListeners();
}
}
Normally I can do this from the UI by importing and calling clearTasks(), however, this I cannot use with WorkManager, my understanding is that WorkManager processes are separate.
So, I come to ask, what ways are there to be able to modify an external value using WorkManager?
This is the callbackDispatcher:
@pragma(
'vm:entry-point') // Mandatory if the App is obfuscated or using Flutter 3.1+
void callbackDispatcher() {
Workmanager().executeTask((task, inputData) {
dev.log(
"Native called background task: $task"); //simpleTask will be emitted here.
dev.log("Time limit, clearing all tasks!");
//Call clearTasks() or find a way to be able to modify the list of tasks of TaskProvider.
return Future.value(true);
});
}
Although I initially tried calling clearTasks() anyway, I can see the log for 'Tasks deleted! (log from TaskProvider.clearTasks)' in the console, but in the widget where I show the task list, I don't see the task being deleted.
@pragma(
'vm:entry-point') // Mandatory if the App is obfuscated or using Flutter 3.1+
void callbackDispatcher() {
Workmanager().executeTask((task, inputData) {
dev.log(
"Native called background task: $task"); //simpleTask will be emitted here.
dev.log("Time limit, clearing all tasks!");
TaskProvider taskProvider = TaskProvider();
taskProvider.clearTasks();
return Future.value(true);
});
}
My idea is to modify various things in the task list, such as deleting them, updating the task status, etc. All this data comes from my provider.
The TaskProvider created in this function is not the same being instanced in your provider. Because the function has to be top level maybe an option would be creating a static ChangeNotifier that works as a WorkManagerNotifier sending a message to all who wants to update:
class WorkManagerNotifier extends ChangeNotifer {
WorkManagerNotifier._();
static final WorkManagerNotifier _instance = WorkManagerNotifier._();
factory WorkManagerNotifier() => _instance;
String? task;
/// maybe an enum or bool to say is completed or failed
void updatedTask(String newTask) {
task = newTask;
notifiyListeners();
}
}
@pragma(
'vm:entry-point') // Mandatory if the App is obfuscated or using Flutter 3.1+
void callbackDispatcher() {
Workmanager().executeTask((task, inputData) {
dev.log(
"Native called background task: $task"); //simpleTask will be emitted here.
dev.log("Time limit, clearing all tasks!");
WorkManagerNotifier().updateTask(task); /// maybe you're interested in the data too?
return Future.value(true);
});
}
And now you can either listen WorkManagerNotifier inside your other providers or use it in your context:
/// main
ChangeNotifierValue(
value: WorkManagerNotifier()
child: MaterialApp...
)
/// where you create your TaskProvider
ChangeNotifierProxyProvider<WorkManagerNotifier, TaskProvider>(
create: (_) => TaskProvider(...), ///
update: (_, workManager, taskProvider) {
if (workManager.task == 'task') {
taskProvider.clear();
}
return taskProvider;
},
child: ...
);
Now when workmanager notifies a new task and it has the name 'task' or something you understand you can clear your provider and use it for as many tasks and input data you desire