Iphone CLLocationmanager有时会卡住
我正在开发一个定期获取用户位置的应用程序。最大的问题是,有时应用程序会被卡住,不再提供更新。即使我(杀死并)重新启动我的应用程序,也不会有任何改变。(为location manager设置的精度值接近100-200米。) 但是,当我启动GoogleMaps应用程序时,几秒钟后它就会得到一个非常准确的位置(如果我切换回去,它会被传送到我的应用程序)。为什么? 以下是一些相关的代码部分: 计时器定期调用timerFiredActionIphone CLLocationmanager有时会卡住,iphone,ios,google-maps,core-location,cllocationmanager,Iphone,Ios,Google Maps,Core Location,Cllocationmanager,我正在开发一个定期获取用户位置的应用程序。最大的问题是,有时应用程序会被卡住,不再提供更新。即使我(杀死并)重新启动我的应用程序,也不会有任何改变。(为location manager设置的精度值接近100-200米。) 但是,当我启动GoogleMaps应用程序时,几秒钟后它就会得到一个非常准确的位置(如果我切换回去,它会被传送到我的应用程序)。为什么? 以下是一些相关的代码部分: 计时器定期调用timerFiredAction -(void) timerFiredAction { i
-(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&stopdationlocation
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;
}
}
有没有人经历过这样的事情?欢迎提出任何意见:)
谢谢 我至少可以确认“被阻止的位置管理器”,尽管在一个稍微不同的上下文中:
根据我的经验,如果您创建了两个具有不同精度设置的位置管理器,对这两个位置管理器都启动更新,然后仅对精度要求较高的位置管理器停止更新,那么另一个位置管理器将不再接收任何更新
显然,您只使用了一个管理器,但您的管理器被卡住的方式似乎是相同的:在上述情况下,还可以使用map应用程序(或任何类似程序)重新启动更新
我的解决方法如下:每当我停止一个管理器时,我也会重置所有其他管理器的距离过滤器(存储在名为myCLLocationManagers
的NSSet
中),如下所示:
CLLocationManager * lm;
CLLocationDistance tmp;
for (lm in myCLLocationManagers){
tmp=lm.distanceFilter;
lm.distanceFilter=kCLDistanceFilterNone;
lm.distanceFilter=tmp;
}
这似乎比我以前的工作(停止并重新启动管理器)更可靠
请注意,
kCLOCATIONACURACYBESTFORNAVISION
和kCLOCATIONACURACYBEST
是(当前)负值,一般来说,您不应该依赖所有这些常量的特定值-无法保证kCLOCATIONACURACYHUNDREDMERS==100
(尽管当前为真)。我之所以提到这一点,是因为它看起来像是在直接比较以米为单位的“精度”变量与这些常量。我对触发的操作有点困惑。你为什么要这么做?出现错误时,出现(无效)locationManager:(CLLocationManager*)manager失败错误:(N错误*)错误,然后重新启动CLManager。这是一种比定期检查状态更好的方法(我认为这是它对您的方法所起的作用)。我也使用这种方法,但只用于监控错误。当计时器在成功更新后触发时,它将设置等待标志。在这种情况下,我不需要(?)启动位置管理器,标志指示它正在更新/定位。最初我有两个管理器,一个用于GPS,一个用于Sig,我认为这是问题的原因,但似乎不是。这段代码只适用于一个实例。force方法(stop&start)有时有帮助,有时没有,这很奇怪。关于准确度,我知道它们是负数,我不应该直接比较,但对于正准确度,它是可比较的(在我的例子中,它们是~100-200)。无论如何,在打印出位置后,我会检查代理的准确性,但当应用程序卡住时,根本不会调用代理。