In IOS, I have to wait longer than expect to get location from callback function. As in android device, I got the location similar to HTML5.geolocation.watchPosition.
cordova -v): 6.1.1cordova platform ls): ios 4.1.1[
desiredAccuracy: 0,
stationaryRadius: 5,
distanceFilter: 1,
activityType: 'AutomotiveNavigation',
// debug: true, // <-- enable this hear sounds for background-geolocation life-cycle.
// stopOnTerminate: false, // <-- enable this
locationProvider: backgroundGeolocation.provider.ANDROID_ACTIVITY_PROVIDER,
interval: 3000, // <!-- poll for position every minute
fastestInterval: 500,
]
In foreground mode, I think we should able to get location as soon as possible like android did. In ios, the location will be callback around 20 sec.
I copy some backgroundgeolocation logs from xcode
2016-07-30 15:10:36.060 my-app[21809:335246] BackgroundGeolocationDelegate didUpdateLocations (operationMode: 1)
2016-07-30 15:10:36.060 my-app[21809:335246] Location age 0.001143
2016-07-30 15:10:36.061 my-app[21809:335246] Better location found: BackgroundLocation: id=0 time=140605179391968 lat=37.60756088 lon=-122.42793323 accu=5 aaccu=-1 speed=32.43 head=3.87 alt=0 type=current debug=0
2016-07-30 15:10:36.061 my-app[21809:335246] BackgroundGeolocationDelegate updated distanceFilter, new: 901.000000, old: 1000.000000
2016-07-30 15:10:36.062 my-app[21809:335246] BackgroundGeolocationDelegate queue BackgroundLocation: id=0 time=140605179391968 lat=37.60756088 lon=-122.42793323 accu=5 aaccu=-1 speed=32.43 head=3.87 alt=0 type=current debug=0
2016-07-30 15:10:36.063 my-app[21809:335246] BackgroundGeolocationDelegate#sync BackgroundLocation: id=0 time=140605179391968 lat=37.60756088 lon=-122.42793323 accu=5 aaccu=-1 speed=32.43 head=3.87 alt=0 type=current debug=0
2016-07-30 15:10:36.063 my-app[21809:335246] CDVBackgroundGeolocation onLocationChanged
2016-07-30 15:10:36.066 my-app[21809:335246] BackgroundGeolocationDelegate didUpdateLocations (operationMode: 1)
2016-07-30 15:10:36.066 my-app[21809:335246] Location age 0.002173
2016-07-30 15:10:36.066 my-app[21809:335246] Better location found: BackgroundLocation: id=0 time=140605217381968 lat=37.60756088 lon=-122.42793323 accu=5 aaccu=-1 speed=32.43 head=3.87 alt=0 type=current debug=0
2016-07-30 15:10:36.066 my-app[21809:335246] BackgroundGeolocationDelegate queue BackgroundLocation: id=0 time=140605217381968 lat=37.60756088 lon=-122.42793323 accu=5 aaccu=-1 speed=32.43 head=3.87 alt=0 type=current debug=0
2016-07-30 15:10:36.074 my-app[21809:335246] #######
2016-07-30 15:10:36.075 my-app[21809:335246] {"speed":32.43,"time":1469866236059.745,"longitude":-122.42793323,"location_type":"current","latitude":37.60756088,"accuracy":5,"heading":3.87,"altitude":0,"altitudeAccuracy":-1,"bearing":3.87}
2016-07-30 15:10:36.075 my-app[21809:335246] BackgroundGeolocationDelegate finish
2016-07-30 15:10:36.076 my-app[21809:335246] BackgroundGeolocationDelegate#sync BackgroundLocation: id=0 time=140605217381968 lat=37.60756088 lon=-122.42793323 accu=5 aaccu=-1 speed=32.43 head=3.87 alt=0 type=current debug=0
2016-07-30 15:10:36.076 my-app[21809:335246] CDVBackgroundGeolocation onLocationChanged
2016-07-30 15:10:36.079 my-app[21809:335246] #######
2016-07-30 15:10:36.080 my-app[21809:335246] {"speed":32.43,"time":1469866236064.071,"longitude":-122.42793323,"location_type":"current","latitude":37.60756088,"accuracy":5,"heading":3.87,"altitude":0,"altitudeAccuracy":-1,"bearing":3.87}
2016-07-30 15:10:36.080 my-app[21809:335246] BackgroundGeolocationDelegate finish
2016-07-30 15:11:04.061 my-app[21809:335246] BackgroundGeolocationDelegate didUpdateLocations (operationMode: 1)
2016-07-30 15:11:04.061 my-app[21809:335246] Location age 0.001529
2016-07-30 15:11:04.061 my-app[21809:335246] Better location found: BackgroundLocation: id=0 time=140605179391968 lat=37.61532676 lon=-122.42415123 accu=5 aaccu=-1 speed=33.57 head=10.9 alt=0 type=current debug=0
2016-07-30 15:11:04.062 my-app[21809:335246] BackgroundGeolocationDelegate updated distanceFilter, new: 1000.000000, old: 901.000000
2016-07-30 15:11:04.062 my-app[21809:335246] BackgroundGeolocationDelegate queue BackgroundLocation: id=0 time=140605179391968 lat=37.61532676 lon=-122.42415123 accu=5 aaccu=-1 speed=33.57 head=10.9 alt=0 type=current debug=0
2016-07-30 15:11:04.064 my-app[21809:335246] BackgroundGeolocationDelegate#sync BackgroundLocation: id=0 time=140605179391968 lat=37.61532676 lon=-122.42415123 accu=5 aaccu=-1 speed=33.57 head=10.9 alt=0 type=current debug=0
2016-07-30 15:11:04.064 my-app[21809:335246] CDVBackgroundGeolocation onLocationChanged
2016-07-30 15:11:04.065 my-app[21809:335246] BackgroundGeolocationDelegate didUpdateLocations (operationMode: 1)
2016-07-30 15:11:04.065 my-app[21809:335246] Location age 0.001688
2016-07-30 15:11:04.066 my-app[21809:335246] Better location found: BackgroundLocation: id=0 time=140605217450192 lat=37.61532676 lon=-122.42415123 accu=5 aaccu=-1 speed=33.57 head=10.9 alt=0 type=current debug=0
2016-07-30 15:11:04.066 my-app[21809:335246] BackgroundGeolocationDelegate queue BackgroundLocation: id=0 time=140605217450192 lat=37.61532676 lon=-122.42415123 accu=5 aaccu=-1 speed=33.57 head=10.9 alt=0 type=current debug=0
2016-07-30 15:11:04.074 my-app[21809:335246] #######
2016-07-30 15:11:04.074 my-app[21809:335246] {"speed":33.57,"time":1469866264060.13,"longitude":-122.42415123,"location_type":"current","latitude":37.61532676,"accuracy":5,"heading":10.9,"altitude":0,"altitudeAccuracy":-1,"bearing":10.9}
2016-07-30 15:11:04.074 my-app[21809:335246] BackgroundGeolocationDelegate finish
2016-07-30 15:11:04.075 my-app[21809:335246] BackgroundGeolocationDelegate#sync BackgroundLocation: id=0 time=140605217450192 lat=37.61532676 lon=-122.42415123 accu=5 aaccu=-1 speed=33.57 head=10.9 alt=0 type=current debug=0
2016-07-30 15:11:04.075 my-app[21809:335246] CDVBackgroundGeolocation onLocationChanged
2016-07-30 15:11:04.079 my-app[21809:335246] #######
2016-07-30 15:11:04.079 my-app[21809:335246] {"speed":33.57,"time":1469866264064.236,"longitude":-122.42415123,"location_type":"current","latitude":37.61532676,"accuracy":5,"heading":10.9,"altitude":0,"altitudeAccuracy":-1,"bearing":10.9}
2016-07-30 15:11:04.080 my-app[21809:335246] BackgroundGeolocationDelegate finish
2016-07-30 15:11:34.047 my-app[21809:335246] BackgroundGeolocationDelegate didUpdateLocations (operationMode: 1)
2016-07-30 15:11:34.048 my-app[21809:335246] Location age 0.001201
2016-07-30 15:11:34.048 my-app[21809:335246] Better location found: BackgroundLocation: id=0 time=140605217402784 lat=37.62390061 lon=-122.42805007 accu=5 aaccu=-1 speed=34.22 head=332.93 alt=0 type=current debug=0
2016-07-30 15:11:34.048 my-app[21809:335246] BackgroundGeolocationDelegate queue BackgroundLocation: id=0 time=140605217402784 lat=37.62390061 lon=-122.42805007 accu=5 aaccu=-1 speed=34.22 head=332.93 alt=0 type=current debug=0
2016-07-30 15:11:34.049 my-app[21809:335246] BackgroundGeolocationDelegate#sync BackgroundLocation: id=0 time=140605217402784 lat=37.62390061 lon=-122.42805007 accu=5 aaccu=-1 speed=34.22 head=332.93 alt=0 type=current debug=0
2016-07-30 15:11:34.049 my-app[21809:335246] CDVBackgroundGeolocation onLocationChanged
2016-07-30 15:11:34.055 my-app[21809:335246] #######
2016-07-30 15:11:34.055 my-app[21809:335246] {"speed":34.22,"time":1469866294046.848,"longitude":-122.42805007,"location_type":"current","latitude":37.62390061,"accuracy":5,"heading":332.93,"altitude":0,"altitudeAccuracy":-1,"bearing":332.93}
2016-07-30 15:11:34.055 my-app[21809:335246] BackgroundGeolocationDelegate finish
2016-07-30 15:11:47.423 my-app[21809:335246] #### backgroundGeoLocation.stopTracking()
2016-07-30 15:11:47.424 my-app[21809:335246] BackgroundGeolocationDelegate stop
Actually android will soon behave same way. iOS does initial sampling by waiting maximum of 20secs to get most accurate initial location. It's a maximum, meaning it can be much sooner (depends on option.desiredAccuracy and provider conditions). However if there will be many people complaining, I will make that interval configurable. So vote.
Edit: Try using meaningful option desiredAccuracy. Something like 100.
Can you suggest the config then?
I want android and iOS to track location of user when in a car to draw a driving lines. So, the foreground and background should be realtime gps tracking.
ANDROID_ACTIVITY_PROVIDER is not suitable for cars, as you sit in it can be recognized as STILL activity (stationary).
I would go for something like:
{
desiredAccuracy: 100,
stationaryRadius: 30,
distanceFilter: 1, //doesn't really matter
activityType: 'AutomotiveNavigation',
interval: 15000,
saveBatteryOnBackground: false
}
Also back to android sampling. Thanks to log I found nice argument why is timed based sampling better than fixed number of samples. Currently iOS waits 15seconds and android waits for 5 location samples.
First 5 samples might be only from network, which is not as accurate as GPS. Thanks to users logs, I can actually confirm this:
Sampling on fixed number might result in network provider only results, because "cold" GPS might take more then 5 samples to get location fix.
[2016/08/09 23:02:37] DistanceFilterLocationProvider:Location change: Location[network 49.******,5.****** acc=38 et=+2m52s269ms {Bundle[mParcelledData.dataSize=448]}] isMoving=false
[2016/08/09 23:02:17] DistanceFilterLocationProvider:Location change: Location[network 49.******,5.****** acc=38 et=+2m32s188ms {Bundle[mParcelledData.dataSize=448]}] isMoving=false
[2016/08/09 23:02:17] DistanceFilterLocationProvider:Location change: Location[network 49.******,5.****** acc=38 et=+2m32s188ms {Bundle[mParcelledData.dataSize=448]}] isMoving=false
[2016/08/09 23:01:59] BackgroundGeolocationPlugin:App is no longer visible
[2016/08/09 23:01:59] BackgroundGeolocationPlugin:App will be paused multitasking=true
[2016/08/09 23:01:57] DistanceFilterLocationProvider:Location change: Location[network 49.******,5.****** acc=38 et=+2m12s237ms {Bundle[mParcelledData.dataSize=448]}] isMoving=false
[2016/08/09 23:01:57] DistanceFilterLocationProvider:Location change: Location[network 49.******,5.****** acc=38 et=+2m12s237ms {Bundle[mParcelledData.dataSize=448]}] isMoving=false
[2016/08/09 23:01:56] DistanceFilterLocationProvider:Setting pace: false
Hi, I have a similar issue with iOS. I am working on an app for my research project that needs to track GPS location every second.
I have the following settings:
{
desiredAccuracy: 0,
stationaryRadius: 1,
distanceFilter: 0,
saveBatteryOnBackground: false,
activityType: 'AutomotiveNavigation',
}
When I start a trip it seems to work fine ... the location changes in real-time. But once I switch from walking to running, or when I drive a car, or when I am on the bus the location tracking only updates every 15-90 seconds, which makes it impossible to detect any stops (e.g. at red lights or bus stops).
For my application I do not care about saving battery life. The goal is to get accurate real-time data for study analysis. I'm also not planning to submit the app to Google Play Store, nor to the Apple App Store.
Could you please show me a way to by-pass any of the energy saving functions and to maximize accuracy and real-time update?
@pbraun there could be multiple problems, but in overall I cannot recommend using this plugin for your use case as it's focusing on battery life.
The biggest one is distanceFilter, you'll need to disable it in code.
The seconds one is iOS specific, which does not allow you to poll for locations in defined time intervals, but rather meters.
In your case, I would go for something much simpler than this plugin. HTML5 or cordova-plugin-geolocation, which don't have any fancy features.
EDIT: cordova-background-geolocation-lt has feature to disable elasticity (distanceFilter). It's free for iOS and for Android you need to buy license.
@mauron85 Thank you for the quick reply. I tried using the cordova-plugin-geolocation, there were two issues with it: 1. for me it didn't work on Android, and 2. it doesn't allow background logging. That is why I switched to this plugin.
Thank you for the cordova-background-geolocation-lt suggestion. I will give that a try.
yeah it should work better with option disableElasticity which basically turns off distanceFilter.
Anyway as there is more and more people asking for this kind of behaviour, I'm thinking about creating bare version to suit your needs.
A bare version would have its own advantages too. What do you think about adding more config options to get more fine grained control? E.g. choose whether to use only the traditional Location Manager or the Activity Types, turn off distance filter and region monitor ...
Do you have more thoughts about the bare version?
What do you think about adding more config options to get more fine grained control?
I'm usually against too many options, because I hate reading long docs and preferer reasonable defaults, BUT it will probably make sense in bare version.
E.g. choose whether to use only the traditional Location Manager or the Activity Type
what do you prefer? I'm not decided about this.
turn off distance filter and region monitor
sure, those will be removed from bare version
My requeriments to the bare version:
I agree with you.
I think it would be good to have the option to use the standard location services as well as the significant changes feature. Having them in one plugin would be convenient but if it's too complicated to put them together maybe it would be better to have two different plugins for it.
I've never worked with native iOS code but I tried to patch the iOS code for this plugin to use the highest possible accuracy and turned off the distance filter but it still didn't have any affect. Maybe I did something wrong.
In LocationManager.m in the configure function I tried to set:
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
Is it even possible to use these options but this set the activity type?
FYI, Since I couldn't quickly figure out how to natively improve the accuracy I found a work around that kind of works for my app. As per your suggestion I used the HTML 5 geolocation feature, which works well for real-time updates, but it doesn't run in the background by itself. I found out that with the "cordova-plugin-background-geolocation" installed and configured, for some reason, it allows me to run the HTML5 geolocation code in the background. I only had to configure the plugin then call start and stop onsuccess, just once. The only disadvantage now is that every time I use the app the HTML5 geolocation feature asks for GPS permission. For some reason the WebView doesn't remember the user's decision. For my use-case that's not a big issue though.
In LocationManager.m in the configure function I tried to set:
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
You also need to disable recalculation of distance filter in LocationManage.m line 585
// replace following line:
// locationManager.distanceFilter = [self calculateDistanceFilter:[lastLocation.speed floatValue]];
// with this:
locationManager.distanceFilter = _config.distanceFilter;
and then replace line 590 - 595 with:
locationManager.distanceFilter = _config.distanceFilter;
[self startUpdatingLocation];
Thank you for the feedback on patching LocationManager.
I vote for having an option to disable distance filter. I do think the maintenance of the separate module for that is more complicated task. I actually need that for React Native, not Cordova app. The module is used for the fitness tracker - in Android it goes fine, but in iOS due to rare position updates the corners are cut and the route becomes very inaccurate.
I would be interested as well. I vote for the disable distance filter option too.
You can now use RAW_LOCATION_PROVIDER to achieve that.