Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting user location every n minutes after app goes to background

I am trying to implement the suggestions given in this post.

Unfortunately the steps are not clear to me. I tried implementing those suggestions, but the backgroundTimeRemaining continues to decrease even after I start and stop locationServices. This is how I developed it:

- (void)applicationDidEnterBackground:(UIApplication *)application {      UIApplication*    app = [UIApplication sharedApplication];      bgTask = [app beginBackgroundTaskWithExpirationHandler:^{         [app endBackgroundTask:bgTask];         bgTask = UIBackgroundTaskInvalid;     }];      // Start the long-running task and return immediately.     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{          // Do the work associated with the task.         self.timer = nil;         [self initTimer];      }); } 

initTimer:

- (void)initTimer {      // Create the location manager if this object does not     // already have one.     if (nil == self.locationManager)         self.locationManager = [[CLLocationManager alloc] init];      self.locationManager.delegate = self;     [self.locationManager startMonitoringSignificantLocationChanges];      if (self.timer == nil) {         self.timer = [NSTimer scheduledTimerWithTimeInterval:0.3                                               target:self                                             selector:@selector(checkUpdates:)                                             userInfo:nil                                              repeats:YES];     } } 

checkUpdates:

- (void)checkUpdates:(NSTimer *)timer{     UIApplication*    app = [UIApplication sharedApplication];     double remaining = app.backgroundTimeRemaining;     if(remaining < 580.0) {         [self.locationManager startUpdatingLocation];          [self.locationManager stopUpdatingLocation];          [self.locationManager startMonitoringSignificantLocationChanges];     }     DbgLog(@"Reminaing %f", app.backgroundTimeRemaining); } 

Does anyone have a suggestion on what might be wrong in my code? Both initTimer and checkUpdates are being called, but only during for the background execution time (+- 10 Mins). I want the app to update the location every n minutes "forever".

My app's UIBackgroundModes is set to location.

UPDATE:

I am now resetting the timer on didUpdateToLocation and didFailWithError. But still the backgroundTimeRemaining keeps decreasing:

- (void)locationManager:(CLLocationManager *)manager  didUpdateToLocation:(CLLocation *)newLocation         fromLocation:(CLLocation *)oldLocation {  NSLog(@"Did Update Location = %f / %f", [newLocation coordinate].latitude, [newLocation coordinate].longitude);  UIApplication*    app = [UIApplication sharedApplication];  bgTask = [app beginBackgroundTaskWithExpirationHandler:^{     [app endBackgroundTask:bgTask];     bgTask = UIBackgroundTaskInvalid; }];  // Start the long-running task and return immediately. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{      // Do the work associated with the task.      [self initTimer];  }); }  - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {  [self.locationManager stopUpdatingLocation];  UIApplication*    app = [UIApplication sharedApplication];  bgTask = [app beginBackgroundTaskWithExpirationHandler:^{     [app endBackgroundTask:bgTask];     bgTask = UIBackgroundTaskInvalid; }];  // Start the long-running task and return immediately. [self initTimer]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{      // Do the work associated with the task.  });  } 

I am also invalidating the timer:

- (void)checkUpdates:(NSTimer *)timer{ UIApplication*    app = [UIApplication sharedApplication]; double remaining = app.backgroundTimeRemaining; if(remaining < 580.0 && remaining > 570.0) {     [self.timer invalidate];     self.timer = nil;     [self.locationManager startUpdatingLocation];      [self.locationManager stopUpdatingLocation];  } DbgLog(@"*************************Checking for updates!!!!!!!!!!! Reminaing %f", app.backgroundTimeRemaining); } 
like image 526
scurioni Avatar asked Apr 19 '12 19:04

scurioni


People also ask

What does location in the background mean?

If the user closes the app, or hits the home button to return to their main screen, then the app's access to location is considered in the background.

What does location while using the app mean?

Precise location: The app can tell your phone's exact location. In the foreground: The app can use your location only when the app is open on your screen or when you ask the app to do something. In the background: The app can use location info at any time, even if you aren't using it.

How do I turn off my location background?

This feature, for example, is accessible via the Settings app on an iPhone and Android. Tap the Settings app, navigate down to Life360, and enter the menu. Hit the button next to Background App Refresh to toggle it off.


1 Answers

To anyone else having a nightmare of a time trying to figure this one out, I have a simple solution.

  1. Study the example from raywenderlich.com. The sample code works perfectly, but unfortunately there's no timer during background location. This will run indefinitely.
  2. Add timer by using this code snippet:

    -(void)applicationDidEnterBackground {   [self.locationManager stopUpdatingLocation];    UIApplication* app = [UIApplication sharedApplication];    bgTask = [app beginBackgroundTaskWithExpirationHandler:^{     [app endBackgroundTask:bgTask];     bgTask = UIBackgroundTaskInvalid;   }];    self.timer = [NSTimer scheduledTimerWithTimeInterval:intervalBackgroundUpdate                                                 target:self.locationManager                                               selector:@selector(startUpdatingLocation)                                               userInfo:nil                                                repeats:YES]; } 
  3. Just don't forget to add "App registers for location updates" in info.plist.

like image 184
HelmiB Avatar answered Sep 24 '22 03:09

HelmiB