flutter_background_geolocation icon indicating copy to clipboard operation
flutter_background_geolocation copied to clipboard

Background geolocation is not working when app is in Background minimized mode in iOS platform

Open moh-moh-pan-phyu-mhwe opened this issue 2 years ago • 20 comments

Your Environment

  • Plugin version: 4.9.0
  • Platform: iOS
  • OS version: 13
  • Device manufacturer / model: iPhone 8
  • Flutter info (flutter doctor):
  • Flutter 3.7.6 • channel stable • https://github.com/flutter/flutter.git Framework • revision 12cb4eb7a0 (3 months ago) • 2023-03-01 10:29:26 -0800 Engine • revision ada363ee93 Tools • Dart 2.19.3 • DevTools 2.20.1
  • Plugin config:
 _backgroundGeo() async {
    bg.BackgroundGeolocation.onLocation(_onLocation);
    bg.BackgroundGeolocation.onMotionChange(_onMotionChange);
    bg.BackgroundGeolocation.onActivityChange(_onActivityChange);
    // bg.BackgroundGeolocation.onProviderChange(_onProviderChange);
    bg.BackgroundGeolocation.onConnectivityChange(_onConnectivityChange);

    // 2.  Configure the plugin
    bg.BackgroundGeolocation.ready(bg.Config(
      desiredAccuracy: bg.Config.DESIRED_ACCURACY_HIGH,
      disableElasticity: true,
      distanceFilter: 10.0,
      stopOnTerminate: false,
      startOnBoot: true,
      logLevel: bg.Config.LOG_LEVEL_VERBOSE,
      notificationTitle: "My App",
      notificationText: "Movement",
      locationAuthorizationRequest: 'Always',
      reset: true,
      stopTimeout: 0,
    )).then((bg.State state) {
      if (!state.enabled) {
        ////
        // 3.  Start the plugin.
        //
        bg.BackgroundGeolocation.start();
      }
    });
  }
---------------------
Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CADisableMinimumFrameDurationOnPhone</key>
	<true/>
	<key>CFBundleDevelopmentRegion</key>
	<string>$(DEVELOPMENT_LANGUAGE)</string>
	<key>CFBundleDisplayName</key>
	<string>Connect GRX</string>
	<key>CFBundleExecutable</key>
	<string>$(EXECUTABLE_NAME)</string>
	<key>CFBundleIdentifier</key>
	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleName</key>
	<string>Connect GRX</string>
	<key>CFBundlePackageType</key>
	<string>APPL</string>
	<key>CFBundleShortVersionString</key>
	<string>$(MARKETING_VERSION)</string>
	<key>CFBundleSignature</key>
	<string>????</string>
	<key>CFBundleVersion</key>
	<string>$(CURRENT_PROJECT_VERSION)</string>
	<key>LSRequiresIPhoneOS</key>
	<true/>
	<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
	<string>Always or When in use description</string>
	<key>NSLocationAlwaysUsageDescription</key>
	<string>Location always</string>
	<key>NSLocationWhenInUseUsageDescription</key>
	<string>When in use description</string>
	<key>NSMotionUsageDescription</key>
	<string>Motion usage description</string>
	<key>UIApplicationSupportsIndirectInputEvents</key>
	<true/>
	<key>UIBackgroundModes</key>
	<array>
		<string>fetch</string>
		<string>location</string>
		<string>processing</string>
	</array>
	<key>UILaunchStoryboardName</key>
	<string>LaunchScreen</string>
	<key>UIMainStoryboardFile</key>
	<string>Main</string>
	<key>UISupportedInterfaceOrientations</key>
	<array>
		<string>UIInterfaceOrientationPortrait</string>
		<string>UIInterfaceOrientationLandscapeLeft</string>
		<string>UIInterfaceOrientationLandscapeRight</string>
	</array>
	<key>UISupportedInterfaceOrientations~ipad</key>
	<array>
		<string>UIInterfaceOrientationPortrait</string>
		<string>UIInterfaceOrientationPortraitUpsideDown</string>
		<string>UIInterfaceOrientationLandscapeLeft</string>
		<string>UIInterfaceOrientationLandscapeRight</string>
	</array>
	<key>UIViewControllerBasedStatusBarAppearance</key>
	<false/>
	<key>BGTaskSchedulerPermittedIdentifiers</key>
	<array>
		<string>com.transistorsoft.fetch</string>
	</array>
</dict>
</plist>

Expected Behavior

When I minimized my iOS app in background, background location should work properly.

Actual Behavior

When I minimized my iOS app in background, background location do NOT work.

Steps to Reproduce

I added iOS configurations properly but I do not add code for backgroundfetch.configure code because I think it already configured in plugin.

Context

Debug logs

Logs
PASTE_YOUR_LOGS_HERE

moh-moh-pan-phyu-mhwe avatar May 17 '23 04:05 moh-moh-pan-phyu-mhwe

See CHANGELOG for latest version.

have you read the wiki “Philosophy of Operation”? You need to go outside and move at least 200 meters before tracking automatically engages in the background.

christocracy avatar May 17 '23 04:05 christocracy

I added these configs and it works properly. Please close this. Thank you.

bg.BackgroundGeolocation.ready(bg.Config( desiredAccuracy: bg.Config.DESIRED_ACCURACY_HIGH, disableElasticity: true, distanceFilter: 10.0, stopOnTerminate: false, startOnBoot: true, logLevel: bg.Config.LOG_LEVEL_VERBOSE, notificationTitle: "My App", notificationText: "Movement", locationAuthorizationRequest: 'Always', reset: true, allowIdenticalLocations: true, preventSuspend: true, showsBackgroundLocationIndicator: true, )).then((bg.State state) { if (!state.enabled) { //// // 3. Start the plugin. // bg.BackgroundGeolocation.start(); } }); }

moh-moh-pan-phyu-mhwe avatar May 18 '23 03:05 moh-moh-pan-phyu-mhwe

Please learn to syntax highlight codeblocks

https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks

christocracy avatar May 18 '23 03:05 christocracy

There is unstable issue of not getting lat long while app is in background (minimized mode) in iOS platform.

In my iOS app, there is timer and call getCurrentPositition in every 5 secs and then saved update lat long values in flutter arraylist.

App is in production mode, use real iPhone and went outside at least 10 km distance by car.

App is in background mode, cannot get updated lat long values in sometimes.

How to handle it? please advice me.

moh-moh-pan-phyu-mhwe avatar May 18 '23 08:05 moh-moh-pan-phyu-mhwe

My issue is exactly same with this ticket number. When app is in background (iOS only) does not register all positions and it "jumps" #802

the red circle is the gaps. line_gap

moh-moh-pan-phyu-mhwe avatar May 18 '23 09:05 moh-moh-pan-phyu-mhwe

In my iOS app, there is timer and call getCurrentPositition in every 5 secs

You don't need to use timers and call .getCurrentPosition().

The plugin automatically detects when the device is moving by monitoring a geofence around the last known position. When the OS informs the plugin that the device has exited this geofence (typically 200 meters), the plugin turns on location services and begins recording location according to your Config.distanceFilter.

Depending on the environment (eg: presence of Wifi signals, distance of cell towers, physical obstructions), this typical 200 meter distance to detect device is moving can be longer.

There is no configuration in the plugin that can change assist this. Make sure you do disable Wifi on your device.

christocracy avatar May 18 '23 13:05 christocracy

I suggest you test this behaviour in the iOS simulator with location simulated with Freeway Drive.

christocracy avatar May 18 '23 13:05 christocracy

The plugin automatically detects when the device is moving by monitoring a geofence around the last known position. When the OS informs the plugin that the device has exited this geofence (typically 200 meters), the plugin turns on location services and begins recording location according to your Config.distanceFilter.

In my case, I do not need to define geofence zone. I just want know the current position wherever I go like tracking. If I remove my timer, can I know the updated lat lng in location event when I go outside?

bg.BackgroundGeolocation.onLocation(_onLocation);

moh-moh-pan-phyu-mhwe avatar May 19 '23 07:05 moh-moh-pan-phyu-mhwe

You can manually change the plug-in state into moving state via method .changePace(true). See api docs.

christocracy avatar May 19 '23 12:05 christocracy

We have been using this plugin for a few years now and we seem to be seeing reports of similar behaviour on iOS. We are seeing gaps appear some time after the screen has been locked but while the device has been in continuous motion and doesn't have obstructions blocking gps signals. We use changePace to force it to stream locations constantly.

spatialbits avatar Jun 16 '23 21:06 spatialbits

We are seeing gaps appear some time after the screen has been locked but

iOS 16.4 made a change to CoreLocation. Upgrade to latest version.

christocracy avatar Jun 16 '23 21:06 christocracy

I assume that's to account for https://github.com/transistorsoft/flutter_background_geolocation/blob/e8070b4d055a96e5ba2f8b4538cf334ff4702fbd/CHANGELOG.md?plain=1#L10 ?

We have showsBackgroundLocationIndicator: true in our config. Is there more in that change that we need?

spatialbits avatar Jun 16 '23 23:06 spatialbits

We are seeing gaps appear some time after the screen has been locked

I have also been observing this behavior.

iOS 16.4 made a change to CoreLocation. Upgrade to latest version

Updating to the latest version works for me (no more gaps), but I want to set showsBackgroundLocationIndicator to false.

Is it possible to eliminate the gaps (more frequent updates) without showing the indicator?

I found this issue on the matter which seems to suggest you can set showIndicator to false with the following conditions:

  • allowsBackgroundLocationUpdates must be set to TRUE or YES
  • distanceFilter must not be set, or set to kCLDistanceFilterNone
  • desiredAccuracy must be kCLLocationAccuracyHundredMeters or better. If you’re using numeric values, it must be set to less than 1000 meters

Would this mean I should set distanceFilter to 0?

kvenn avatar Jul 25 '23 00:07 kvenn

distanceFilter to 0?

Yes. You’ll get a location about every second.

christocracy avatar Jul 25 '23 00:07 christocracy

Thank you for your reply. I set distanceFilter to 0 and, as you said, it updates about every second. This has caused much higher battery consumption (4x what it was previously from early tests on a real iOS device).

Is there any way to achieve my desired effect given the new iOS changes?

  • Not consume too much battery
  • Update reliably every 10-20 meters while moving
  • Not show the blue indicator at all times while moving

Possibly setting setSuspend to true and bringing my desired distanceFilter back?

Thanks again.

kvenn avatar Jul 27 '23 17:07 kvenn

Have you updated to the latest version?

I suggest you follow Apple’s new guidelines and accept the enabling of the location indicator.

christocracy avatar Jul 27 '23 20:07 christocracy

Understood. I'm on the latest version and all the behavior is as you described.

We attempted to show the indicator, but user satisfaction has decreased significantly.

Right now I have distanceFilter set to 0 and have a throttler to minimize the network requests from the location attempting to send every second.

I will continue tinkering and trying to find the best solution, but I would love any suggestions, if you can think of any (as you're the pro!). Trial and error on my setSuspend + distanceFilter approach hasn't yielded conclusive results.

Thank you

kvenn avatar Aug 28 '23 02:08 kvenn

I'm on the latest version

What "Latest version", exactly?

christocracy avatar Aug 28 '23 03:08 christocracy

When I sent that message in July, I was on ^4.11.1

And now I'm on ^4.12.2.

Phone version I've primarily been testing on is iOS 16.6. I also have another device I've been running on iOS 17, but it has been behaving similarly to 16.6 (as far as I can tell).

kvenn avatar Aug 28 '23 03:08 kvenn

This issue is stale because it has been open for 30 days with no activity.

github-actions[bot] avatar May 04 '24 01:05 github-actions[bot]

This issue was closed because it has been inactive for 14 days since being marked as stale.

github-actions[bot] avatar May 18 '24 01:05 github-actions[bot]

To update for anyone finding this issue, I'm no longer seeing the behavior that requires setting distanceFilter to 0.

Either OS'es past 16.6 or versions of the library over 4.12.2 are no showing this issue in my testing.

kvenn avatar May 18 '24 14:05 kvenn