在iOS 7后台模式下有效跟踪用户的问题

时间:2014-02-14 00:01:47

标签: ios objective-c gps core-location background-process

我正在编写代码以不断跟踪应用CoreLocation的用户。由于我无法始终保持GPS状态,因此我在StartMonitoringSignificantLocationChange中使用AppDelegate来检测重大变化。我在location注册了UIBackgroundMode。 在didUpdateLocations方法中,我检查与先前记录位置的当前距离。如果它很重要,我会应用StopMonitoringSignificantLocationChangeStartUpdatingLocation来获取准确的位置。同时我启动计时器(30秒)以查看用户是静止还是移动。如果用户不再移动,我会再次应用StopUpdatingLocationStartMonitoringSignificantLocationChange。 我还在AppDelegate: -(void)applicationWillResignActive:(UIApplication *)application中定义了一个后台任务,如下所示:

- (void)applicationWillResignActive:(UIApplication *)application
{
    if (![[GeoSampleManager sharedManager] isLiveTracking])
    {
        GeoSampleManager *manager = [HTSGeoSampleManager sharedManager];

        [manager.locationManager stopMonitoringSignificantLocationChanges];

        self.bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
        [application endBackgroundTask:self.bgTask];
            self.bgTask = UIBackgroundTaskInvalid;
        }];

        [manager.locationManager startMonitoringSignificantLocationChanges];
    }
}

当应用程序进入前台时关闭后台任务:

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    if(self.bgTask != UIBackgroundTaskInvalid)
    {
        [[UIApplication sharedApplication] endBackgroundTask:self.bgTask];
        self.bgTask = UIBackgroundTaskInvalid;
    }
}

这是我的didUpdateLocations方法:

- (void)locationManager:(CLLocationManager *)manager
 didUpdateLocations:(NSArray *)locations
{
    CLLocation* newLocation = [locations lastObject];

    if(self.isLiveTracking)
    {
        //Test that the horizontal accuracy does not indicate an invalid measurement
        if (newLocation.horizontalAccuracy < 0 || newLocation.horizontalAccuracy > 200)
        {
            return;
        }

        if([self.lastLocation distanceFromLocation:newLocation] > 0)
        {
            //Create and save a GeoSample
            [GeoSampleManager createSampleForLocation:newLocation onTrip:self.activeTrip];

            self.lastLocation = newLocation;
        }
    }
    else
    {
        if([self.lastLocation distanceFromLocation:newLocation] > 0)
        {
            [self.locationManager stopMonitoringSignificantLocationChanges];
    self.idleChecker = [NSTimer scheduledTimerWithTimeInterval:30 target:self selector:@selector(checkIdle:) userInfo:nil repeats:YES];

    [self.locationManager startUpdatingLocation];
            self.isLiveTracking = YES;
        }
    }
}

最后这里是计时器方法:

- (void)checkIdle:(NSTimer*)timer
{
    if(abs([self.lastLocation.timestamp timeIntervalSinceNow]) >= 30.0)
    {
        //Stopping the idle-time checking timer
    [self.idleChecker invalidate];
    self.idleChecker = nil;

    [self.locationManager stopUpdatingLocation];
    [self.locationManager startMonitoringSignificantLocationChanges];
        self.isLiveTracking = NO;
    }
}

然而,该应用程序暂停(有时在5-10秒后,有时在10分钟后)并停止接收位置更新。因为我正在努力解决这个问题一个多月而且我已经尝试了几乎所有可能的解决方案,我非常感谢您能以任何方式帮助我解决问题。

干杯

1 个答案:

答案 0 :(得分:2)

  • 除非设置了正确的多任务处理模式(例如导航应用程序),否则后台任务将在10分钟后死亡,在这种情况下您需要保持GPS状态。
  • 您必须打开GPS或在后台播放声音。你说你不能一直保持GPS,但如果是这种情况,那么你所看到的可能是预期的行为(或者我误读了什么)。
  • 请参阅可用的不同CLLocationAccuracy常量:

可在:https://developer.apple.com/library/ios/documentation/CoreLocation/Reference/CoreLocationConstantsRef/Reference/reference.html#//apple_ref/c/data/kCLLocationAccuracyKilometer

获取
extern const CLLocationAccuracy kCLLocationAccuracyBestForNavigation;
extern const CLLocationAccuracy kCLLocationAccuracyBest;
extern const CLLocationAccuracy kCLLocationAccuracyNearestTenMeters;
extern const CLLocationAccuracy kCLLocationAccuracyHundredMeters;
extern const CLLocationAccuracy kCLLocationAccuracyKilometer;
extern const CLLocationAccuracy kCLLocationAccuracyThreeKilometers;

至少这个“可能”有助于管理你的GPS电池消耗,如果你一直保持运行。