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
152 stars 112 forks source link

Flutter stops when closing app from recent apps #264

Closed DH-555 closed 2 months ago

DH-555 commented 3 months ago

When I close the app from recent apps after the service is running and the notification is showing, the app stops.

For example, the demo prints in the console a thing every X seconds. If the app is closed from recent apps, it's not being printed anymore.

Dev-hwang commented 3 months ago

Is the notification content updated even if you close the app in recent apps?

If so, the foreground service has not stopped.

In the example, the count console log is printed in the Widget.

When the app is terminated, the widget is disposed, so the count console log is no longer printed.

Try printing the console log in TaskHandler onRepeatEvent.

  // Called every [ForegroundTaskOptions.interval] milliseconds.
  @override
  void onRepeatEvent(DateTime timestamp) {
    FlutterForegroundTask.updateService(notificationText: 'count: $_count');

    // Send data to main isolate.
    FlutterForegroundTask.sendDataToMain(_count);

    _count++;

    print('count: $_count');
  }
Dev-hwang commented 3 months ago

The code to be processed in the background must be written in TaskHandler.

And if you stop the app in debug mode(according to your dev environment...), the foreground service may stop. You should test it in profile/release mode.

TheValkDokk commented 3 months ago

Are you testing this on the physical device or emulate ? Which platform ? If it's Xiaomi then it will kill the foreground when user remove the app from the recent apps screen

Dev-hwang commented 3 months ago

@TheValkDokk

yes... it seems that it is impossible to prevent the foreground service from being terminated on Xiaomi devices.

many developers have reported that this issue also exists when implementing native apps.

For Xiaomi devices, DontKillMyApp might be helpful...

fuadarradhi commented 3 months ago

where do you print console, in taskhandler or in main ui?

I am using xiaomi for development now, and have not found any problems

DH-555 commented 2 months ago

where do you print console, in taskhandler or in main ui?

How to print it in task handler? From what I understand I'm printing it on task handler

DH-555 commented 2 months ago

Are you testing this on the physical device or emulate ? Which platform ? If it's Xiaomi then it will kill the foreground when user remove the app from the recent apps screen

Emulator

Dev-hwang commented 2 months ago

@DH-555

In the example, the count console log is printed in the Widget State.

class _ExamplePageState extends State<ExamplePage> {
  void _onReceiveTaskData(Object data) {
    if (data is int) {
      // here
      print('count: $data');
    }
  }
}

As you know, widgets are disposed when the app terminates. and the communication port of this plugin is destroyed.

If the communication port is destroyed, data cannot be passed between Main Isolate(UI) and TaskHandler.

Therefore, the FlutterForegroundTask.sendDataToMain function does not work.

Try print(count) in the onRepeatEvent callback.

@override
void onRepeatEvent(DateTime timestamp) {
  FlutterForegroundTask.updateService(notificationText: 'count: $_count');

  // here
  print('count: $_count');
}
DH-555 commented 2 months ago

I do it there. Also I'm running there geolocator, and it seems to stop too getting the location. Maybe it's something specific to geolocator and not to this package. No idea 🤔

Dev-hwang commented 2 months ago

@DH-555

hmm.. have you tested it with a real device?

i don't know if it will help you, here an example of implementing a background service using the fl_location plugin.

https://github.com/Dev-hwang/flutter_foreground_task_example/tree/main/location_service

Dev-hwang commented 2 months ago

@DH-555

If you want to use the Geolocator plugin..

Don't call Geolocator.getCurrentPosition repeatedly in the onRepeatEvent callback.

Instead, subscribe to Geolocator.getPositionStream in the onStart callback.

DH-555 commented 2 months ago

I'm going to try with your recommended plugin, let me try and huge thanks for this amazing package and support :)

fuadarradhi commented 2 months ago

I do it there. Also I'm running there geolocator, and it seems to stop too getting the location. Maybe it's something specific to geolocator and not to this package. No idea 🤔

why you use geolocator if owner of this packgage also have location stream service packgage :)

btw, fl_location very stable with, plus flutter_activity_recognition also

DH-555 commented 2 months ago

I tested the plugin provided by you and the example. It works perfectly, unlike geolocator that is being destroyed, so the solution is basically using the provided plugin.

The only problem is that I'm unable now with the stream opened to perform periodic location updates instead of constantly as the interval is not working. Also the printing is not working like previously

Dev-hwang commented 2 months ago

@DH-555

Are you testing on iOS?

Check readme

:baby_chick: iOS

We can also launch flutter_foreground_task on the iOS platform. However, it has the following limitations.

This plugin does not implement BGTaskScheduler. I simply used Timer.scheduledTimer to allow short interval while the app is in use. Timer.scheduledTimer only runs in the background for about 30 seconds. This is a limitation of iOS. You must return to the app to continue working.

https://github.com/Dev-hwang/flutter_foreground_task/blob/a61fbcbf6208239fc698ef0f9427fa036719e6e6/ios/Classes/service/BackgroundService.swift#L305

DH-555 commented 2 months ago

@Dev-hwang Nope, I'm testing in Android. I managed to solve the issue by restarting the app after establishing the interval in your location plugin.

Huge thanks for everything!

DH-555 commented 2 months ago

Hello! Update on this: I'm using the example you provided to send the location from the user to an appwrite server. The Issue is that it stops sending it while the app is closed, so I receive updates only with the app opened. Not sure how to overcome that issue