Search code examples
androidflutterbackground-fetch

Periodic location report of device using flutter


I need to report the current location of the device using a flutter app. I need to do that continiuesly even when the app is closed. I currently implemented it using background_fetch which does the job about every 15 minutes. It works well when the app is open or minimized. But when the app is closed, it functions in Headless mode and doesn't work. the Exception is:

MissingPluginException(No implementation found for method getLocation on channel lyokone/location)

It seems that in Headless mode, not all the app is loaded in memory. I don't have any idea how to solve it.

Also I tried using an Isolate but I face with a new exception:

native function 'Window_sendPlatformMessage' (4 arguments) cannot be found.

Anybody knows how to solve these problems or have any new idea to do the location tracking?


Solution

  • Another option is use package https://github.com/Lyokone/flutterlocation https://github.com/Lyokone/flutterlocation/wiki/Background-Location-Updates
    Support To get location updates even your app is closed, https://github.com/Lyokone/flutterlocation/wiki/Background-Location-Updates might have bugs

    Also from transistorsoft and provide Android Headless Mod but need license
    transistorsoft package https://github.com/transistorsoft/flutter_background_geolocation/wiki/Android-Headless-Mode
    Android Headless Mod https://github.com/transistorsoft/flutter_background_geolocation/wiki/Android-Headless-Mode

    code snippet

    import 'package:flutter_background_geolocation/flutter_background_geolocation.dart' as bg;
    
    void headlessTask(bg.HeadlessEvent headlessEvent) async {
      print('[BackgroundGeolocation HeadlessTask]: $headlessEvent');
      // Implement a 'case' for only those events you're interested in.
      switch(headlessEvent.name) {
        case bg.Event.TERMINATE:
          bg.State state = headlessEvent.event;
          print('- State: $state');
          break;
        case bg.Event.HEARTBEAT:
          bg.HeartbeatEvent event = headlessEvent.event;
          print('- HeartbeatEvent: $event');
          break;
        case bg.Event.LOCATION:
          bg.Location location = headlessEvent.event;
          print('- Location: $location');
          break;
        case bg.Event.MOTIONCHANGE:
          bg.Location location = headlessEvent.event;
          print('- Location: $location');
          break;
        case bg.Event.GEOFENCE:
          bg.GeofenceEvent geofenceEvent = headlessEvent.event;
          print('- GeofenceEvent: $geofenceEvent');
          break;
        case bg.Event.GEOFENCESCHANGE:
          bg.GeofencesChangeEvent event = headlessEvent.event;
          print('- GeofencesChangeEvent: $event');
          break;
        case bg.Event.SCHEDULE:
          bg.State state = headlessEvent.event;
          print('- State: $state');
          break;
        case bg.Event.ACTIVITYCHANGE:
          bg.ActivityChangeEvent event = headlessEvent.event;
          print('ActivityChangeEvent: $event');
          break;
        case bg.Event.HTTP:
          bg.HttpEvent response = headlessEvent.event;
          print('HttpEvent: $response');
          break;
        case bg.Event.POWERSAVECHANGE:
          bool enabled = headlessEvent.event;
          print('ProviderChangeEvent: $enabled');
          break;
        case bg.Event.CONNECTIVITYCHANGE:
          bg.ConnectivityChangeEvent event = headlessEvent.event;
          print('ConnectivityChangeEvent: $event');
          break;
        case bg.Event.ENABLEDCHANGE:
          bool enabled = headlessEvent.event;
          print('EnabledChangeEvent: $enabled');
          break;
      }
    }
    
    void main() {
      runApp(HelloWorld());
      // Register your headlessTask:
      BackgroundGeolocation.registerHeadlessTask(headlessTask);
    }