CLLocationmanager有时会卡住

时间:2012-02-16 10:07:16

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

我正在开发一个定期获取用户位置的应用程序。最大的问题是,有时应用程序会卡住,不再提供更新。即使我(杀死并)重启我的应用程序,也没有任何变化。 (为位置管理员设置的准确度值接近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] ; 

    }

}

启动和停止方法只需验证位置管理器是否为零,如果是,则调用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; 
    }
}

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

1 个答案:

答案 0 :(得分:0)

我至少可以确认“被阻止的位置管理员”,但情况略有不同:

根据我的经验,如果您创建两个具有不同准确度设置的位置管理器,则为两者启动更新,然后仅停止具有更高准确度要求的更新,然后另一个不再接收任何更新。

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

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

myCLLocationManagers

这似乎比我之前的woraround(停止并重新启动管理员)更可靠。

请注意 CLLocationManager * lm; CLLocationDistance tmp; for (lm in myCLLocationManagers){ tmp=lm.distanceFilter; lm.distanceFilter=kCLDistanceFilterNone; lm.distanceFilter=tmp; } kCLLocationAccuracyBestForNavigation是(当前)负值,而且一般来说,您不应该依赖所有这些常量的特定值 - 不能保证{{1} (虽然目前是真的)。我只提到这个,因为看起来你直接比较米的“精度”变量和那些常数。