Background geolocation is not working when app is in Background minimized mode in iOS platform
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
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.
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(); } }); }
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
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.
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.
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.
I suggest you test this behaviour in the iOS simulator with location simulated with Freeway Drive.
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);
You can manually change the plug-in state into moving state via method .changePace(true). See api docs.
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.
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.
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?
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?
distanceFilter to 0?
Yes. You’ll get a location about every second.
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.
Have you updated to the latest version?
I suggest you follow Apple’s new guidelines and accept the enabling of the location indicator.
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
I'm on the latest version
What "Latest version", exactly?
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).
This issue is stale because it has been open for 30 days with no activity.
This issue was closed because it has been inactive for 14 days since being marked as stale.
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.