My application needs to track user location changes in the background and works fine as long as user moves around.
When user stops and CLLocationManager
pauses after 10-20 minutes or so. It is indicated by this notification:
-(void)locationManagerDidPauseLocationUpdates:(CLLocationManager *)manager{}
And this is also fine with me. Great, I save some battery, etc.
The problem is that CLLocationManager
never wakes up when user starts moving again and following delegate methods are never fired until I put my application to the foreground (gets active):
//Never called back after CLLocationManager pauses:
-(void)locationManagerDidResumeLocationUpdates:(CLLocationManager *)manager{}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{}
Why is locationManagerDidResumeLocationUpdates
never called after device starts moving again? Shouldn't GPS resume automatically also (since was paused automatically)?
Is there a way to resume GPS without user's interaction?
Application has following declared in Info.plist file:
And my CLLocationManager settings are:
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager setActivityType:CLActivityTypeFitness];
//I WANT pauses to save some battery, etc... That is why following line is commented out (default)
//[locationManager setPausesLocationUpdatesAutomatically:NO];
locationManager.distanceFilter = kCLLocationAccuracyNearestTenMeters;
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
[locationManager startUpdatingLocation];
If you search for pausesLocationUpdatesAutomatically
on the Apple forums you'll find a recent question along similar lines which has had a response from an Apple developer. I won't repost it directly here since it is a private forum, but the gist is that the location pausing is for instances when the user forgets that they have got a location aware app running and have stopped using it. By pausing updates their battery won't be drained as quickly. Unfortunately it's not possible to know whether new movement is them resuming the activity or doing something else, so updates don't resume until the app comes back to the foreground. Their suggestion is to catch the pause call and get the user's attention somehow to get them to open the app if they still want updates.
EDIT:
From Apple's own documentation of pausesLocationUpdatesAutomatically. They suggest:
After a pause occurs, it is your responsibility to restart location services again when you determine that they are needed. Core Location calls the
locationManagerDidPauseLocationUpdates(_:)
method of your location manager's delegate to let you know that a pause has occurred. In that method, you might configure a local notification whose trigger is of typeUNLocationNotificationTrigger
and is set to notify when the user exits the current region. The message for the local notification should prompt the user to launch your app again so that it can resume updates.
The apple doc is very weak on that topic. property pausesLocationUpdatesAutomatically
allows apple to shut down GPS when apple thinks that the user does not need GPS.
Although not documented, it seems that setting this property leads to a stop of GPS in background mode.
Various posts describe the problems with that property: , e.g here:
iOS 6 CoreLocation does not work
In iOS 6 AutoPause doesn't work Stanislav Dvoychenko posts the reccomendation of Apple:
[Update - 4-Mar-2013]. I looked through the Apple's presentation for location changes in iOS6 and they suggest to use the region changes monitoring to "un-pause" once you get region changes event. Though this is not suitable for my scenarios as user might go/run/drive for a kilometer or two until such an event happens.
I suggest: set that property to false.
If you can, use startMonitoringSignificantLocationChanges because then (Apple):
If you start this service and your application is subsequently terminated, the system automatically relaunches the application into the background if a new event arrives.
You can try combine this with finer-grained tracking once your app wakes up (e.g. user re-enters it).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With