background_locator_fixed icon indicating copy to clipboard operation
background_locator_fixed copied to clipboard

It doesn't call initCallback

Open Mahm0ud-Ahmed opened this issue 1 year ago • 2 comments

When the service is started, initCallback is not called, and the callback method is called directly.

LocationCallbackHandler

import 'dart:async';
import 'package:background_locator_2/location_dto.dart';

import 'package:guard_user/src/presentation/view_model/blocs/data_bloc/api_data_bloc.dart';

import 'location_service_repository.dart';

@pragma('vm:entry-point')
class LocationCallbackHandler {
  static late ApiDataBloc? locationActionBloc;

  @pragma('vm:entry-point')
  static Future<void> initCallback(Map<dynamic, dynamic> params) async => LocationServiceRepository().init(params);

  @pragma('vm:entry-point')
  static Future<void> disposeCallback() async => LocationServiceRepository().dispose();

  @pragma('vm:entry-point')
  static Future<void> callback(LocationDto newLocation) async => LocationServiceRepository().callback(newLocation);

  @pragma('vm:entry-point')
  static Future<void> notificationCallback() async => print('***notificationCallback');
}

LocationServiceRepository

import 'dart:ui';

import 'package:background_locator_2/location_dto.dart';
import 'package:guard_user/src/core/utils/constant.dart';

class LocationServiceRepository {
  static const String isolateName = kLocationBackgroundIsolate;

  static final LocationServiceRepository _instance = LocationServiceRepository._();
  LocationServiceRepository._();
  factory LocationServiceRepository() => _instance;

  Future<void> init(Map<dynamic, dynamic> params) async {
    IsolateNameServer.lookupPortByName(isolateName)?.send(null);
    print('*********init location service*********');
  }

  Future<void> dispose() async {
    IsolateNameServer.lookupPortByName(isolateName)?.send(null);
    print('*********dispose location service*********');
  }

  Future<void> callback(LocationDto locationDto) async {
    IsolateNameServer.lookupPortByName(isolateName)?.send(locationDto.toJson());
    print('*********callback location service*********');
  }
}

TrackingService

It is called by startLocator() from inside the TrackingService class.

import 'dart:async';
import 'dart:isolate';
import 'dart:ui';

import 'package:background_locator_2/background_locator.dart';
import 'package:background_locator_2/location_dto.dart';
import 'package:background_locator_2/settings/android_settings.dart';
import 'package:background_locator_2/settings/ios_settings.dart';
import 'package:background_locator_2/settings/locator_settings.dart';
import 'package:guard_user/src/core/utils/constant.dart';
import 'package:location_permissions/location_permissions.dart';

import '../../config/l10n/generated/l10n.dart';
import '../../utils/app_logger.dart';
import '../service_interface.dart';
import 'location_callback_handler.dart';

class TrackingService implements ServiceInterface {
  late final ReceivePort receivePort = ReceivePort();

  Stream<LocationDto>? _locationStream;

  late bool serviceIsRunning;

  @override
  String get name => "Tracking Service";

  @override
  Future<void> initializeService() async {
    serviceIsRunning = false;
    locationStream;
    AppLogger.logDebug('$name Success initialization');
  }

  void registerPort({ReceivePort? receive, String? portName}) async {
    if (IsolateNameServer.lookupPortByName(portName ?? kLocationBackgroundIsolate) != null) {
      IsolateNameServer.removePortNameMapping(portName ?? kLocationBackgroundIsolate);
    }

    IsolateNameServer.registerPortWithName(
      receive?.sendPort ?? receivePort.sendPort,
      portName ?? kLocationBackgroundIsolate,
    );
  }

  Stream<LocationDto> get locationStream {
    if (_locationStream == null) {
      Stream<dynamic> dataStream = receivePort.asBroadcastStream();
      _locationStream = dataStream.where((event) => event != null).map(
            (json) => LocationDto.fromJson(json),
          );
    }
    return _locationStream!;
  }

  LocationDto? fromJson(dynamic data) {
    return data != null ? LocationDto.fromJson(data) : null;
  }

  void updateNotification(String message) async {
    await BackgroundLocator.updateNotificationText(
      title: S.current.tracking_site_activated_title,
      bigMsg: message,
    );
  }

  void startLocator() async {
    final result = await _checkServicePermission();
    if (result) {
      await BackgroundLocator.initialize();
      await _runService();
      serviceIsRunning = await BackgroundLocator.isServiceRunning();
      print('======<<<<<<  $serviceIsRunning');
    }
  }

  Future<bool> _checkServicePermission() async {
    PermissionStatus access = await LocationPermissions().checkPermissionStatus();
    if (access != PermissionStatus.granted || access != PermissionStatus.restricted) {
      access = await LocationPermissions().requestPermissions(permissionLevel: LocationPermissionLevel.locationAlways);
    }
    return access == PermissionStatus.granted || access == PermissionStatus.restricted;
  }

  Future<void> _runService() async {
    if (!await BackgroundLocator.isServiceRunning() && !await BackgroundLocator.isRegisterLocationUpdate()) {
      return await BackgroundLocator.registerLocationUpdate(
        LocationCallbackHandler.callback,
        initCallback: LocationCallbackHandler.initCallback,
        disposeCallback: LocationCallbackHandler.disposeCallback,
        autoStop: false,
        iosSettings: const IOSSettings(
          showsBackgroundLocationIndicator: true,
          stopWithTerminate: true,
          accuracy: LocationAccuracy.NAVIGATION,
          distanceFilter: 0,
        ),
        androidSettings: AndroidSettings(
          accuracy: LocationAccuracy.NAVIGATION,
          interval: 10,
          distanceFilter: 0,
          client: LocationClient.google,
          androidNotificationSettings: AndroidNotificationSettings(
            notificationChannelName: kLocationBackgroundIsolate,
            notificationTitle: S.current.tracking_being_activated_site_title,
            // notificationMsg: 'Track location in background',
            notificationBigMsg: S.current.tracking_notification_body_title,
            // notificationIconColor: Colors.grey,
            notificationTapCallback: LocationCallbackHandler.notificationCallback,
          ),
        ),
      );
    } else if (await BackgroundLocator.isRegisterLocationUpdate()) {
      await BackgroundLocator.unRegisterLocationUpdate();
      return _runService();
    }
  }

  void stopTracking({String? portName}) async {
    if (IsolateNameServer.lookupPortByName(portName ?? kLocationBackgroundIsolate) != null) {
      IsolateNameServer.removePortNameMapping(portName ?? kLocationBackgroundIsolate);
    }
    await BackgroundLocator.unRegisterLocationUpdate();
    serviceIsRunning = await BackgroundLocator.isServiceRunning();
    _locationStream = null;
  }

  // Singleton
  TrackingService.int();
  static TrackingService? _instance;
  factory TrackingService() => _instance ??= TrackingService.int();
}

Mahm0ud-Ahmed avatar Nov 03 '23 20:11 Mahm0ud-Ahmed

Did you find any solution ?

dhruv-kabariya avatar Mar 21 '24 17:03 dhruv-kabariya

Same issue here, doesn't call initCallback

rajeev1982 avatar Jun 26 '24 16:06 rajeev1982