HomeiOS DevelopmentiOS background location works in Debug however not in Launch (Flutter)

iOS background location works in Debug however not in Launch (Flutter)


I’m utilizing Flutter with flutter_background_service and geolocator to get location updates within the background.

In debug mode, background location works tremendous even when the app is minimized or the display screen is locked.

However when working in launch mode or putting in the app through TestFlight, it stops sending any background location updates.

I’ve enabled the next in Xcode

Background Modes

data.plist

UIBackgroundModes

    fetch
    location
    remote-notification
    processing


NSLocationAlwaysAndWhenInUseUsageDescription
Your location is required even when the app is within the background to trace journeys.

NSLocationAlwaysUsageDescription
Your location is required even when the app is within the background to trace journeys.

NSLocationTemporaryUsageDescriptionDictionary

    LocationTracking
    This app wants exact location for varsity bus monitoring and security monitoring functions.


NSLocationWhenInUseUsageDescription
Your location is required to trace journeys whereas the app is open.

BGTaskSchedulerPermittedIdentifiers

    dev.flutter.background.refresh

BackgorundService

class BackgroundServiceController extends ChangeNotifier {
  static ultimate BackgroundServiceController _instance =
      BackgroundServiceController._internal();
  manufacturing facility BackgroundServiceController() => _instance;
  BackgroundServiceController._internal();
  ultimate FlutterBackgroundService _service = FlutterBackgroundService();

  Future initializeService({
    required int? disInterval,
    required int? timeInterval,
  }) async {
    SessionController().setDistanceAndTimeInterval(
      disInterval: disInterval.toString(),
      timeInterval: timeInterval.toString(),
    );

    ultimate isRunning = await _service.isRunning();
    if (isRunning) {
      await Future.delayed(const Length(seconds: 1));
      _service.invoke('setData');
      return;
    }

    const AndroidNotificationChannel channel = AndroidNotificationChannel(
      'my_foreground', 
      'MY FOREGROUND SERVICE', 
      description:
          'This channel is used for essential notifications.', 
      significance: Significance.low, 
    );

    ultimate FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
        FlutterLocalNotificationsPlugin();

    if (Platform.isIOS || Platform.isAndroid) {
      await flutterLocalNotificationsPlugin.initialize(
        const InitializationSettings(
          iOS: DarwinInitializationSettings(),
          android: AndroidInitializationSettings('brand'),
        ),
      );
    }
    await flutterLocalNotificationsPlugin
        .resolvePlatformSpecificImplementation()
        ?.createNotificationChannel(channel);
    await _service.configure(
      androidConfiguration: AndroidConfiguration(
        onStart: onStart,
        autoStart: true,
        isForegroundMode: true,
        autoStartOnBoot: true,
        notificationChannelId: 'my_foreground',
        initialNotificationTitle: 'Location Service',
        initialNotificationContent: 'Initializing...',
        foregroundServiceNotificationId: 888,

        foregroundServiceTypes: [AndroidForegroundType.location],
      ),
      iosConfiguration: IosConfiguration(
        autoStart: true,
        onForeground: onStart,
        onBackground: onIosBackground,
      ),
    );

    attempt {
      await _service.startService();
    } catch (e) {

    }
    whereas (!(await _service.isRunning())) {
      await Future.delayed(const Length(milliseconds: 200));
    }
    await Future.delayed(const Length(seconds: 3));
    _service.invoke('setData');
  }

  Future stopService() async {
    ultimate isRunning = await _service.isRunning();
    if (isRunning) {
      _service.invoke("stopService");
    } else {
    }
  }

  Future isServiceRunning() async {
    return await _service.isRunning();
  }
}

@pragma('vm:entry-point')
void onStart(ServiceInstance service) async {
  // DartPluginRegistrant.ensureInitialized();

  WidgetsFlutterBinding.ensureInitialized();
  await AppConstants.init();
  await SessionController().init();
  ultimate FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
      FlutterLocalNotificationsPlugin();
  ultimate disInterval = SessionController().disInterval ?? 20;
  ultimate timeInterval = SessionController().timeInterval ?? 10;
  StreamSubscription? positionStream;
  ultimate homeViewModel = HomeViewModel();

  void startLocationTracking() async {
    if (positionStream != null) {
      return;
    }

    DateTime? lastSentTime;
    positionStream =
        Geolocator.getPositionStream(
          locationSettings: const LocationSettings(
            distanceFilter: 0,
            accuracy: LocationAccuracy.bestForNavigation,
          ),
        ).pay attention((place) async {
          ultimate now = DateTime.now();

          if (lastSentTime == null ||
              now.distinction(lastSentTime!).inSeconds >= (timeInterval)) {
            lastSentTime = now;

            attempt {
              await homeViewModel.pushLiveLocation(place: place);
            } catch (e) {
            }
          } else {
          }
        });
  }

  service.on('stopService').pay attention((occasion) async {
    await positionStream?.cancel();
    positionStream = null;
    await service.stopSelf();
  });

  service.on('setData').pay attention((knowledge) async {
    ultimate disInterval = SessionController().disInterval ?? 20;
    ultimate timeInterval = SessionController().timeInterval ?? 10;

    await Future.delayed(const Length(seconds: 5));
    startLocationTracking();
  });

  if (service is AndroidServiceInstance &&
      await service.isForegroundService()) {
    flutterLocalNotificationsPlugin.present(
      888,

      'Monitoring location in background',
      'Background location is on to maintain the app up-tp-date along with your location. That is required for foremost options to work correctly when the app will not be working.',
      const NotificationDetails(
        android: AndroidNotificationDetails(
          'my_foreground',
          'MY FOREGROUND SERVICE',
          icon: 'ic_stat_notification', 
          ongoing: true,
          styleInformation: BigTextStyleInformation(
            'Background location is on to maintain the app up-to-date along with your location. '
            'That is required for foremost options to work correctly when the app will not be working.',
            contentTitle: 'Monitoring location in background',
            htmlFormatContent: true,
          ),
        ),
      ),
    );

    // service.setForegroundNotificationInfo(
    //   title: "Location Monitoring",
    //   content material: "Monitoring your location in background",
    // );
  }
}

@pragma('vm:entry-point')
Future onIosBackground(ServiceInstance service) async {
  // DartPluginRegistrant.ensureInitialized();
  WidgetsFlutterBinding.ensureInitialized();
  await AppConstants.init();
  await SessionController().init();
  ultimate homeViewModel = HomeViewModel();
  attempt {
    ultimate disInterval = SessionController().disInterval ?? 20;

    ultimate sub =
        Geolocator.getPositionStream(
          locationSettings: const LocationSettings(
            distanceFilter: 0,

            accuracy: LocationAccuracy.bestForNavigation,
          ),
        ).pay attention((place) async {
          attempt {
            await homeViewModel.pushLiveLocation(place: place);
          } catch (e) {
          }
        });

    await Future.delayed(const Length(seconds: 30));
    await sub.cancel();
  } catch (e) {
  }

  return true;
}

I additionally checked that the app has At all times Permit location permission in iOS Settings

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments