Yasuki
Yasuki

Reputation: 15

Update external values with WorkManager

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.

Upvotes: 0

Views: 204

Answers (1)

EdwynZN
EdwynZN

Reputation: 5611

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

Upvotes: 0

Related Questions