如何在应用程序被杀死时获得准确的位置更新?

How to get accurate location update when application is killed?

我正在开发一个基于位置的应用程序,用户可以在其中存储多个位置,当用户经过该存储位置附近时,应用程序将通过本地通知通知用户。

我使用了以下代码来实现此功能:


-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
   if([[UIApplication sharedApplication] backgroundRefreshStatus] == UIBackgroundRefreshStatusDenied){

         [self showAlertWithTitle:@"" andMessage:@"The app doesn't work without the Background App Refresh enabled. To turn it on, go to Settings > General > Background App Refresh."];
  }else if([[UIApplication sharedApplication] backgroundRefreshStatus] == UIBackgroundRefreshStatusRestricted){

    [self showAlertWithTitle:@"" andMessage:@"The functions of this app are limited because the Background App Refresh is disable."];
  } else {
    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) {

        // This "afterResume" flag is just to show that he receiving location updates
        self.shareModel.afterResume = YES;

        self.shareModel.anotherLocationManager = [[CLLocationManager alloc]init];
        self.shareModel.anotherLocationManager.delegate = self;
        self.shareModel.anotherLocationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; //kCLLocationAccuracyBestForNavigation
        self.shareModel.anotherLocationManager.activityType = CLActivityTypeOtherNavigation;
        [self.shareModel.anotherLocationManager startUpdatingLocation];
                 self.shareModel.anotherLocationManager.pausesLocationUpdatesAutomatically = YES;


        if(IS_OS_8_OR_LATER) {
            if ([self.shareModel.anotherLocationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
                [self.shareModel.anotherLocationManager requestWhenInUseAuthorization];
            }
            [self.shareModel.anotherLocationManager requestAlwaysAuthorization];
        }

        [self.shareModel.anotherLocationManager startMonitoringSignificantLocationChanges];
    }
  }
}

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {

CLLocation *currentLocation = [locations lastObject];

latitudeTemp = currentLocation.coordinate.latitude;
longitudeTemp = currentLocation.coordinate.longitude;

[self locationChangeLogic];    

//If the timer still valid, return it (Will not run the code below)
if (self.shareModel.timer)
    return;

self.shareModel.bgTask = [BackgroundTaskManager sharedBackgroundTaskManager];
[self.shareModel.bgTask beginNewBackgroundTask];

//Restart the locationMaanger after 30 Seconds
self.shareModel.timer = [NSTimer scheduledTimerWithTimeInterval:30
                                                         target:self
                                                       selector:@selector (restartLocationUpdates)
                                                       userInfo:nil
                                                        repeats:YES];

//Will only stop the locationManager after 10 seconds, so that we can get some accurate locations
//The location manager will only operate for 10 seconds to save battery
NSTimer * delay10Seconds;
delay10Seconds = [NSTimer scheduledTimerWithTimeInterval:10
                                                  target:self
                                                selector:@selector(stopLocationDelayBy10Seconds)
                                                userInfo:nil
                                                 repeats:YES];
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
      [self.shareModel.anotherLocationManager startMonitoringSignificantLocationChanges];
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.


//Remove the "afterResume" Flag after the app is active again.
self.shareModel.afterResume = NO;

if(self.shareModel.anotherLocationManager)
    [self.shareModel.anotherLocationManager stopMonitoringSignificantLocationChanges];

self.shareModel.anotherLocationManager = [[CLLocationManager alloc]init];
self.shareModel.anotherLocationManager.delegate = self;
self.shareModel.anotherLocationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; //kCLLocationAccuracyBestForNavigation;
self.shareModel.anotherLocationManager.activityType = CLActivityTypeOtherNavigation;
[self.shareModel.anotherLocationManager startUpdatingLocation];

if(IS_OS_8_OR_LATER) {
    if ([self.shareModel.anotherLocationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
        [self.shareModel.anotherLocationManager requestWhenInUseAuthorization];
    }
    [self.shareModel.anotherLocationManager requestAlwaysAuthorization];
}
[self.shareModel.anotherLocationManager startMonitoringSignificantLocationChanges];
}

通过使用上面的代码,即使应用程序被用户杀死,我也可以获得位置,但没有达到应有的准确度。有时我没有得到位置,有时我在通过那个存储的位置后得到位置。我需要在用户进入该特定半径时准确显示位置通知。

请帮我解决这个问题。

提前致谢。

区域监控(地理围栏)满足我的要求。

您可以使用以下几个 link 获取更多信息:

  1. https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/LocationAwarenessPG/RegionMonitoring/RegionMonitoring.html

  2. http://www.rapidvaluesolutions.com/tech_blog/geofencing-using-core-location-for-regional-monitoring-in-ios-applications/

谢谢大家..