I'm developing an iPhone app that will need to keep updating location even when app is in the background.
What I do is:
set background mode for Location Update
set desiredAccuracy = kCLLocationAccuracyBestForNavigation
implement -(void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;
call [locationManager startUpdatingLocation]
While the app enter background, it will keep update the location by about only 10 minutes. and then, the update is stop.
Do someone know why?
How can I do a long time location update in background?
Thanks!
From Apple Documentation
You enable location support from the Background modes section of the Capabilities tab in your Xcode project. (You can also enable this support by including the UIBackgroundModes key with the location value in your app’s Info.plist file.) Enabling this mode does not prevent the system from suspending the app, but it does tell the system that it should wake up the app whenever there is new location data to deliver. Thus, this key effectively lets the app run in the background to process location updates whenever they occur.
It seems like setting the background mode should be enough. I got this to work in an app I'm working on, the only difference I see is that I have the pausesLocationUpdatesAutomatically set to NO.
To solve this in my QT app when the App would go into the background I would stopUpdatingLocation, decrease the accuracy from Best to kCLLocationAccuracyNearestTenMeters AND set a distance filter from None to 50 meters, then startUpdatingLocation.
You could try a lower filter if you need more granular location data.
Related
Done with the setting up the required pre-requisites. set distance filter , accuracy filter and using start updating locations.
Able to receive location co-ordinates once moved to background for some time say 10 -15 minutes. Later Didreceivelocation updates not returning any co-ordinates even after the device is moved beyond the provided distance filter. But when app brought back to foreground, it returns location co-ordinates.
Any solution to receive location co-ordinates when ever the user moves to set distance filter irrespective of the app being in foreground or background.
Any way to keep the app to behave as always run in foreground even though app is in background mode?
I think you have to look at this answer to make sure you've set up everything right:
allowsBackgroundLocationUpdates in CLLocationManager in iOS9
"This new property is explained in the WWDC session What's New in Core Location"
Put a code in that view controller
$if ([self.locationManager respondsToSelector:#selector(setAllowsBackgroundLocationUpdates:)]) {
[self.locationManager setAllowsBackgroundLocationUpdates:YES];
}
After my app is killed I want to relaunch the app based on the location.speed paramater, I mean to say when the device speed is>5kmph I want my app to get open and one button needs to be clicked programatically?
NOT POSSIBLE.
You can not execute part of code when you process is killed. Its as simple as that.
You can do this in android with background sevice which run even when you app gets killed because background service is different process. But iOS don't allow to create background service.
Set allowsBackgroundLocationUpdates = true
The default value is NO for allowsBackgroundLocationUpdates
If your app uses location in the background (without showing the blue status bar) you have to set allowsBackgroundLocationUpdates to YES in addition to setting the background mode capability in Info.plist. Otherwise location updates are only delivered in foreground. The advantage is that you can now have location managers with background location updates and other location managers with only foreground location updates in the same app. You can also reset the value to NO to change the behavior.
My iPhone app registers for significant location change. When on location change is called, I start beacon region monitoring for all the beacon in certain range of user's location.
My app needs to identify that user has entered into a beacon region (irrespective of whether app is running or not). To achieve this, we did following things:
-- set notifyEntryStateOnDisplay flag to true for beacon regions:
beaconRegion.notifyEntryStateOnDisplay = true;
-- set Required background modes in pList to bluetooth-central. for ref. this link
I am not sure what got it working. But it turns out our app does not turn location services off, once started.
Is it possible to get significant location change update and beacon region entered update when location service is off?
Do I need to set Required background modes to get this working in background?
When you using iBeacon to monitor for specific region it will always display location icon on status bar, even when app is closed.
To disable location service for your app try to call method bellow for all you registered regions when going to background:
- (void)stopMonitoringForRegion:(CLRegion *)region
And to use iBeacon in background you actually need not "bluetooth-central" mode but "location".
You do not need to keep background mode - location updates ON for beacon ranging.
For background execution, just use UIBackgroundTaskIdentifier and your code will work in background as well.
check my answer iBeacon ranging in the background? here.
With the M7 chip in the latest iOS devices one can get programmatically notified as the user goes from stationary to running, walking, etc using CMMotionActivityManager. Stava and Runkeeper have both used this to auto-pause GPS polling (shut off the GPS antenna) when it detects the user isn't moving via the M7, and then re-enable GPS updates once they are moving again. It is able to do this while the app is in the background state, which is the key here.
The issue I run into while duplicating this functionality is that if I turn off GPS updates while my app is in the background I stop receiving activity updates, and can no longer detect when the user moves again via the M7 to turn the GPS back on.
If I leave the GPS running the whole time I'll continue to get movement updates from Core Motion the entire time the app is in the background.
I'm assuming they aren't playing white-noise or some other cheap trick to stay active. How did they go about this?
RunKeeper actually does use the audio trick to stay awake. If you open up the app package and check their Info.plist you will see that it registers for the background audio mode. This is how they pull off periodic audio notifications of your distance, speed, and pace. It is also how they stay awake during your run while minimizing battery drain.
If you noticed that the Location Services icon (the triangle in the status bar) disappears completely while using RunKeeper then they definitely are not using any type of location tracking to accomplish background execution. Even activating geo-fences and significant location change monitoring would cause the Location Services icon to appear.
They also aren't using the M7 to stay awake because it doesn't work that way. An update from the M7-related CoreMotion APIs will not wake up your app from sleep. When they app does wake up they would be able to query the Motion Activity and Step history and maybe try to compute something, but I doubt it would be all that accurate.
Finally you should note that the Auto-pause APIs were introduced in iOS 6 before the release of the iPhone 5s and M7 chip. They are orthogonal concepts.
have you considered experimenting with
application:performFetchWithCompletionHandler:
in the app delegate? You can't control how often it is called, but depending on the app, it can be every ~15 minutes. You can then launch the CMMotionActivityManager from there to query M7 results.
It's not entirely clear what functionality you are trying to replicate, but the M7 chip records all of the activity, regardless of whether your app is running. So you can simply query in the background and update step totals or activity type totals.
What I noticed when you turn off GPS, app will not execute any code in background for iOS 7, app looks like in inactive state. So better while moving to background use startMonitoringSignificantLocationChanges and also get updates from your location manager. Means simultenoulsy use both service startUpdatingLocation on user state change and startMonitoringSignificantLocationChanges in Background.
So when user Turn on GPS, while you used startMonitoringSignificantLocationChanges your app will receive
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
Better check here in background itself what wrong with CoreMotion Framework. And try to restart it.
Because wihtout M7 chip device I am able to read Accelerometer reading in such case.
If your location manager is working in Active mode, to enable background mode you need to do this three steps:
Check that [Target / Capabilities / Background Modes / Location updates] is enabled.
[locationManager requestAlwaysAuthorization];
locationManager.allowsBackgroundLocationUpdates = YES;
First, check if you have set up the background behave of your app.
Go to target - capabilities section and check Background mode for location updates.
Dear fellow developers,
I am trying hard to find a solution for my problem regarfing CLLocationManager.
I use a CLLocationManager instance in my Application. If the user selects the Home button on the device or terminates the application I want the location services to stop.
Therefor I call [self.locationManager stopUpdatingLocation]; - But this somehow doesn't work. The application enters the background and the small location arrow in the upper right corner of the status bar don't disappear. Even if I add [self.locationManager release] or self.locationManager.delegate = nil; - the location tracking don't stop :-/
It only disappears if I go to my device settings and switch off location services for the app. Whenever I switch back to location service enabled I immediately get a purple colored arrow next to the switch toggle and the icon reappears in the status bar.
My question is how can I turn off location services when the app enters the background or is terminated?
Thanks a lot in advance and have a nice day :-)
Your location is disabled. The location service icon "meaning" has changed on iOS 5. Take a look at this question: https://apple.stackexchange.com/questions/27463/why-is-the-location-services-icon-always-present
I Quote the answer:
It's a new feature in ios 5 called "region Monitoring"
The reason it's active even if the app is closed is that this feature
runs in iOS 5 core and notifies all apps that are registered when they
have entered or left a specific geo-fence.
Reminders does that when you use a location based reminder.
Although the location icon appears at all time. This actually has very
minimal impact on the battery due to apple really optimizing this
feature by using cell and wifi mostly.
Your app is working ok. The system behaviour is the one who changed.
You do it the right way. When entering background, it's ok if some delegate methods are called for some seconds. That should stop.
Where do you stop the location updates ? Are you sure it is triggered ? If yes, are your delegate method called even if the visual indicators tell something else ?
Are you sure you don't trigger a method that reactivate the location update after you have stopped it (because for example you can receive some updates even after stopped).
For instance if you started monitoring a significant location change, then you should unsubscribe from it with the corresponding pair method. If you are using region enter, then until you unsubscribe, the system will notify your delegates.