2014-02-14 18 views
0

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

- (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]; 
    } 
} 

我关闭后台任务时,应用程序eneters前景:

- (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分钟后),并停止接收位置更新。由于我在这个问题上挣扎了一个多月,而且我尝试了几乎所有可能的解决方案,我非常感谢你能以任何方式帮助我解决问题。

干杯

+0

你曾经从应用程序切换器中删除应用程序吗? – sangony

+0

不,它只是在锁定屏幕时发送到背景。 – Behrang

+0

看看以前的帖子。它可能会给你一个想法(看所有的答案)。 http://stackoverflow.com/questions/18946881/background-location-services-not-working-in-ios-7 – sangony

回答

2
  • Backgrounding任务将在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电池消耗,如果你把它运行的所有时间。

+0

谢谢您的意见@jeef。由于电池消耗,我无法保持GPS,因此,当用户不移动30秒时,我将其关闭。但是,我使用StartMonitoringSignificantLocationChange来检查GSM/WIFI信号并检测用户的移动。万一用户移动,我再次打开GPS。 GPS('StartUpdatingLocation')和GSM/WIFI('StartMonitoringSignificantLocationChanges')之间的切换似乎不能在后台模式下工作。 – Behrang

+0

@Behrang重要通常意味着1000米(下一个GSm单元格),这是你想要的吗? – AlexWien

+0

在这里寻找不同的模式:这(可能)帮助但不直接或许与你想做什么 - https://developer.apple.com/library/ios/documentation/CoreLocation/Reference/CoreLocationConstantsRef/Reference/reference .html#// apple_ref/c/data/kCLLocationAccuracyBestForNavigation – Jeef