【问题标题】:CLLocationmanager gets stuck sometimesCLLocationmanager 有时会卡住
【发布时间】:2012-03-07 17:32:02
【问题描述】:

我正在开发一个定期获取用户位置的应用程序。最大的问题是有时应用程序会卡住,不再提供更新。即使我(杀死并)重新启动我的应用程序,也没有任何改变。 (为位置管理器设置的准确度值接近 100-200 米。) 但是,当我启动谷歌地图应用程序时,它会在几秒钟内获得一个非常准确的位置(如果我切换回来,它会传送到我的应用程序)。为什么 ? 以下是一些相关的代码部分:

timerFiredAction 由计时器定期调用。

-(void) timerFiredAction
{
    if (isStillWaitingForUpdate)
    {
         successiveTimerActivationCount ++;
         // force LM restart if value too big , e.g. 30 ( stop + start )
         return;
    }
    successiveTimerActivationCount = 0 ;
    isStillWaitingForUpdate = YES;
    /* isRecordingX is always true */ 
    if (isSignificant && isRecordingSig) [self startSignificant ];
    if (isGPS && isRecordingGPS) [self startGps];
}

// this is called in delegate method only 
-(void) timerStopLocationServices
{
    isStillWaitingForUpdate = NO;
    if (isGPS) [ self stopGps] ;
    if (isSignificant) [self stopSignificant];
}


- (void)locationManager:(CLLocationManager *)manager  didUpdateToLocation:(CLLocation *)newLocation   fromLocation:(CLLocation *)oldLocation 
{
    // verify accuracy and stuff
    if ( isStillWaitingForUpdate &&  _other_validations_ ) 
    {
    // store it
    [self timerStopLocationServices] ; 

    }

}

start 和 stop 方法只是验证 locationmanager 是否为 nil,如果是,则调用 createManager 然后调用 start 和 stopUpdatingLocation。

LM 的创建如下所示:

-(void)createManager
{
    @synchronized (self)
    {
    if (locationManager != nil) {
        [self releaseManager];  // stop timer, stop updating , reelase previous if exists
    } 
    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self; 
    double desired;
    // accuracy is an init param, snap to one smaller constant
    // generally 100-200
    if (accuracy >= kCLLocationAccuracyThreeKilometers)   desired = kCLLocationAccuracyThreeKilometers; else
    if (accuracy >= kCLLocationAccuracyKilometer)         desired = kCLLocationAccuracyKilometer; else
    if (accuracy >= kCLLocationAccuracyHundredMeters)     desired = kCLLocationAccuracyHundredMeters; else
    if (accuracy >= kCLLocationAccuracyNearestTenMeters)  desired = kCLLocationAccuracyNearestTenMeters; else
    if (accuracy >= kCLLocationAccuracyBest)              desired = kCLLocationAccuracyBest; else        
    if (accuracy >= kCLLocationAccuracyBestForNavigation) desired = kCLLocationAccuracyBestForNavigation;

    locationManager.desiredAccuracy = desired;
    locationManager.distanceFilter = distanceFilter; 
    }
}

有没有人经历过这样的事情?欢迎任何想法:) 谢谢!

【问题讨论】:

  • 我对触发的动作有点困惑。你为什么要这样做?发生错误时有 (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error 然后重新启动您的 CLManager。这是比定期检查状态更好的方法(我认为这是你的方法)
  • 我也使用该方法,但仅用于监控错误。当定时器在成功更新后触发时,它会设置等待标志。它可以多次触发而不获取更新(例如每 3 秒),在这种情况下,我不需要(?)启动位置管理器,并且标志表明它现在正在更新/定位。

标签: iphone ios google-maps core-location cllocationmanager


【解决方案1】:

我至少可以确认“被屏蔽的位置管理器”,尽管上下文略有不同:

根据我的经验,如果您创建了两个具有不同精度设置的位置管理器,对两者都开始更新,然后只停止对精度要求更高的位置管理器的更新,那么另一个将不再接收任何更新。

您显然只使用了一个管理器,但您的管理器卡住的方式似乎是相同的:在上述情况下,也可以使用地图应用程序(或任何类似应用程序)重新启动更新。

我的解决方法如下:每当我停止一位经理时,我也会重置所有其他经理的距离过滤器(存储在名为 myCLLocationManagersNSSet 中),如下所示:

   CLLocationManager * lm; 
   CLLocationDistance tmp;
   for (lm in myCLLocationManagers){
      tmp=lm.distanceFilter;
      lm.distanceFilter=kCLDistanceFilterNone;
      lm.distanceFilter=tmp;
   }

这似乎比我之前的解决方法(停止并重新启动管理器)更可靠。

请注意,kCLLocationAccuracyBestForNavigationkCLLocationAccuracyBest 是(当前)负值,一般来说,您不应该依赖所有这些常量的特定值 - 不能保证 kCLLocationAccuracyHundredMeters==100(尽管目前是真的) .我之所以提到这一点,是因为您似乎是在直接将一个以米为单位的“准确度”变量与这些常数进行比较。

【讨论】:

  • 最初我有两个管理器,一个用于 GPS,一个用于 Sig,我认为这是问题的原因,但似乎不是。此代码仅适用于一个实例。
  • 强制方法(stop&start)有时有帮助,有时没有,这很奇怪。关于准确性,我知道它们是负面的,我不应该进行直接比较,但对于正面的准确性,它是可比较的(在我的情况下,它们是 ~100-200)。无论如何,我在打印出位置后检查了委托的准确性,但是当应用程序卡住时,根本没有调用委托。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-18
  • 2018-08-06
  • 1970-01-01
  • 1970-01-01
  • 2018-09-16
  • 2011-09-23
相关资源
最近更新 更多