skip to Main Content

currently I am us this plugin to get the background location of a user, works great with ios but fails on android after recent updates and the plugin progress stalled, I am now faced with the issue below

so, in my main class i have this

 @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    // onLineStatus = UserSimplePreferences.getUsername() ?? ''
    onLineStatus = UserSimplePrefences.getButtonStatus() ?? false;
    displayToastMessage(onLineStatus.toString(), context);
    osmController = MapController(
      initMapWithUserPosition: true,
      //initPosition: initPosition,
    );
    osmController.addObserver(this);
    scaffoldKey = GlobalKey<ScaffoldState>();

    if (IsolateNameServer.lookupPortByName(
            LocationServiceRepository.isolateName) !=
        null) {
      IsolateNameServer.removePortNameMapping(
          LocationServiceRepository.isolateName);
    }

    IsolateNameServer.registerPortWithName(
        port.sendPort, LocationServiceRepository.isolateName);

    port.listen(
      (dynamic data) async {
        if (data != null) await updateUI(data);
      },
    );
    initPlatformState();
    
  }

  Future<void> updateUI(LocationDto data) async {
   

    await _updateNotificationText(data);

 
  }

  Future<void> _updateNotificationText(LocationDto data) async {
 

    await BackgroundLocator.updateNotificationText(
        title: "Your location is updated",
        msg: "${DateTime.now()}",
        bigMsg: "${data.latitude}, ${data.longitude}");
  }

  Future<void> initPlatformState() async {
    print('Initializing...');
    await BackgroundLocator.initialize();
   
    await BackgroundLocator.isServiceRunning();
   
  }

  Future<void> _startLocator() async {
    Map<String, dynamic> data = {'countInit': 1};
    return await BackgroundLocator.registerLocationUpdate(
        LocationCallbackHandler.callback,
        initCallback: LocationCallbackHandler.initCallback,
        initDataCallback: data,
        disposeCallback: LocationCallbackHandler.disposeCallback,
        iosSettings: IOSSettings(
            accuracy: LocationAccuracy.NAVIGATION,
            distanceFilter: 0,
            stopWithTerminate: true),
        autoStop: false,
        androidSettings: AndroidSettings(
            accuracy: LocationAccuracy.NAVIGATION,
            interval: 5,
            distanceFilter: 0,
            client: LocationClient.google,
            androidNotificationSettings: AndroidNotificationSettings(
                notificationChannelName: 'Location tracking',
                notificationTitle: 'Start Location Tracking',
                notificationMsg: 'Track location in background',
                notificationBigMsg:
                    'Background location is on to keep the app up-tp-date with your location. This is required for main features to work properly when the app is not running.',
                notificationIconColor: Colors.grey,
                notificationTapCallback:
                    LocationCallbackHandler.notificationCallback)));
  }

This is the LocationRepositoryClass

class LocationServiceRepository {
  static LocationServiceRepository _instance = LocationServiceRepository._();

  LocationServiceRepository._();

  factory LocationServiceRepository() {
    return _instance;
  }

  static const String isolateName = 'LocatorIsolate';

  int _count = -1;

  Future<void> init(Map<dynamic, dynamic> params) async {
    //TODO change logs
    print("***********Init callback handler");
    if (params.containsKey('countInit')) {
      dynamic tmpCount = params['countInit'];
      if (tmpCount is double) {
        _count = tmpCount.toInt();
      } else if (tmpCount is String) {
        _count = int.parse(tmpCount);
      } else if (tmpCount is int) {
        _count = tmpCount;
      } else {
        _count = -2;
      }
    } else {
      _count = 0;
    }
    print("$_count");
    await setLogLabel("start");
    final SendPort? send = IsolateNameServer.lookupPortByName(isolateName);
    send?.send(null);
  }

  Future<void> dispose() async {
    print("***********Dispose callback handler");
    print("$_count");
    await setLogLabel("end");
    final SendPort? send = IsolateNameServer.lookupPortByName(isolateName);
    send?.send(null);
  }

  @pragma('vm:entry-point')
  Future<void> callback(LocationDto locationDto) async {
    print('$_count location in dart: ${locationDto.toString()}');
    await setLogPosition(_count, locationDto);
    final SendPort? send = IsolateNameServer.lookupPortByName(isolateName);
    send?.send(locationDto);//error here
    _count++;
  }

  static Future<void> setLogLabel(String label) async {
    final date = DateTime.now();
    // await FileManager.writeToLogFile(
    //     '------------n$label: ${formatDateLog(date)}n------------n');
  }

  static Future<void> setLogPosition(int count, LocationDto data) async {
    final date = DateTime.now();
    // await FileManager.writeToLogFile(
    //     '$count : ${formatDateLog(date)} --> ${formatLog(data)} --- isMocked: ${data.isMocked}n');
  }

  static double dp(double val, int places) {
    num mod = pow(10.0, places);
    return ((val * mod).round().toDouble() / mod);
  }

  static String formatDateLog(DateTime date) {
    return date.hour.toString() +
        ":" +
        date.minute.toString() +
        ":" +
        date.second.toString();
  }

  static String formatLog(LocationDto locationDto) {
    return dp(locationDto.latitude, 4).toString() +
        " " +
        dp(locationDto.longitude, 4).toString();
  }
}

and this is the locationCallbackHandler class

class LocationCallbackHandler {
  static Future<void> initCallback(Map<dynamic, dynamic> params) async {
    LocationServiceRepository myLocationCallbackRepository =
        LocationServiceRepository();
    await myLocationCallbackRepository.init(params);
  }

  static Future<void> disposeCallback() async {
    LocationServiceRepository myLocationCallbackRepository =
        LocationServiceRepository();
    await myLocationCallbackRepository.dispose();
  }

  @pragma('vm:entry-point')
  static void callback(LocationDto locationDto) async {
    LocationServiceRepository myLocationCallbackRepository =
        LocationServiceRepository();
    await myLocationCallbackRepository.callback(locationDto);
  }

  static Future<void> notificationCallback() async {
    print('***notificationCallback');
  }
}

Everthing was working fine until this update with flutter and kotlin, Now i have the error

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Invalid argument: is a regular instance: Instance of 'LocationDto'
E/flutter (26006): #0      _SendPort._sendInternal (dart:isolate-patch/isolate_patch.dart:249:43)
E/flutter (26006): #1      _SendPort.send (dart:isolate-patch/isolate_patch.dart:230:5)
E/flutter (26006): #2      LocationServiceRepository.callback
package:drivers_app/tabPages/location_service_reposirtory.dart:59

The error points to this code

@pragma('vm:entry-point')
  Future<void> callback(LocationDto locationDto) async {
    print('$_count location in dart: ${locationDto.toString()}');
    await setLogPosition(_count, locationDto);
    final SendPort? send = IsolateNameServer.lookupPortByName(isolateName);
    send?.send(locationDto); //error here
    _count++;
  }

There is no reply from the plugin developer, Any help would be appreciated.

2

Answers


  1. Chosen as BEST ANSWER

    https://github.com/Yukams/background_locator_fixed/pull/53

    There were some errors after updating flutter to version 3, If you run into this error then please visit the above website for the fix.


  2. I was facing this issue, Flutter version 3.7.7 : "Unhandled Exception: Invalid argument: is a regular instance: Instance of ‘LocationDto’", just had to format it into a Json, locationDto.toJson().

    @pragma('vm:entry-point')
    Future<void> callback(LocationDto locationDto) async {
      print('$_count location in dart: ${locationDto.toString()}');
      await setLogPosition(_count, locationDto);
      final SendPort? send = IsolateNameServer.lookupPortByName(isolateName);
      send?.send(locationDto.toJson()); //corrected.
      _count++;
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search