Dev-hwang / flutter_foreground_task

This plugin is used to implement a foreground service on the Android platform.
https://pub.dev/packages/flutter_foreground_task
MIT License
149 stars 109 forks source link

Send sendport to the foreground task #284

Open TheAlbertDev opened 4 weeks ago

TheAlbertDev commented 4 weeks ago

We have an application that uses the Drift database. Until now, we were working with version 6.2.1 of the Flutter Foreground Task and sending the sendport to the Drift isolate to the foreground so that the foreground could perform database operations.

Now, we have migrated to version 8.10.4 of the plugin, and we see that sendports can no longer be sent to the foreground. What is the new recommended way to proceed with the new version to send sendports to the foreground?

Dev-hwang commented 3 weeks ago

Hello, @TheAlbertDev

You can send sendPort to UI in a new way.

This plugin supports two-way communication between TaskHandler and UI in new version.

Therefore, there is no need to use sendPort for communication. Please see the readme for more details.

https://github.com/Dev-hwang/flutter_foreground_task?tab=readme-ov-file#hatched_chick-deepening

// version 6.2.0
class FirstTaskHandler extends TaskHandler {
  @override
  void onStart(DateTime timestamp, SendPort? sendPort) async {
    // Send data to main isolate.
    final ReceivePort newReceivePort = ReceivePort();
    final SendPort newSendPort = newReceivePort.sendPort;
    sendPort?.send(newSendPort);
  }
}

class _ExamplePageState extends State<ExamplePage> {
  void _onReceiveTaskData(Object data) {
    print('onReceiveTaskData: $data');
  }

  @override
  void initState() {
    super.initState();

    final ReceivePort newReceivePort = FlutterForegroundTask.receivePort;
    newReceivePort?.listen(_onReceiveTaskData);
  }
}
// version 8.10.4
void main() {
  // Initialize port for communication between TaskHandler and UI.
  FlutterForegroundTask.initCommunicationPort();
  runApp(const ExampleApp());
}

class MyTaskHandler extends TaskHandler {
  @override
  Future<void> onStart(DateTime timestamp, TaskStarter starter) async {
    // Send data to main isolate.
    final ReceivePort newReceivePort = ReceivePort();
    final SendPort newSendPort = newReceivePort.sendPort;
    FlutterForegroundTask.sendDataToMain(newSendPort);
  }
}

class _ExamplePageState extends State<ExamplePage> {
  void _onReceiveTaskData(Object data) {
    print('onReceiveTaskData: $data');
  }

  @override
  void initState() {
    super.initState();
    // Add a callback to receive data sent from the TaskHandler.
    FlutterForegroundTask.addTaskDataCallback(_onReceiveTaskData);
  }

  @override
  void dispose() {
    // Remove a callback to receive data sent from the TaskHandler.
    FlutterForegroundTask.removeTaskDataCallback(_onReceiveTaskData);
    super.dispose();
  }
}
TheAlbertDev commented 3 weeks ago

Hello @Dev-hwang, and thank you for your response. What we want to do is send to the TaskHandler the sendport offered by drift for its own isolate, so that the TaskHandler can directly save data collected from a Bluetooth device into the database. The application is designed to operate in the background, meaning without the app being active or with the phone locked, so I’m not sure if sending the data to the UI is a viable option.