CLLocationmanager иногда зависает - PullRequest
1 голос
/ 16 февраля 2012

Я работаю над приложением, которое периодически получает местоположение пользователя. Большая проблема в том, что иногда приложение застревает, обновления не доставляются. Даже если я (убью и) перезапущу свое приложение, ничего не изменится. (Значения точности, установленные для менеджера местоположения, составляют около 100-200 метров.) НО, когда я запускаю приложение Google Maps, через несколько секунд оно получает очень точное местоположение (которое доставляется моему приложению, если я переключаюсь обратно). Зачем ? Вот некоторые соответствующие части кода:

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 просто проверяют, является ли менеджер местоположения нулем, если да, они вызывают createManager, а затем вызывают start & stopUpdatingLocation.

Создание ЛМ выглядит так:

-(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 голосов
/ 17 февраля 2012

Я могу, по крайней мере, подтвердить «заблокированные менеджеры местоположений», хотя и в несколько ином контексте:

По моему опыту, если вы создадите два менеджера местоположений с разными настройками точности, запустите обновления для обоих, а затем только остановитеобновления для одного с более высоким требованием точности, тогда другое больше не получает никаких обновлений.

Вы, очевидно, используете только одного менеджера, но способ, которым ваш менеджер застревает, кажется, тот же: В случаеКак описано выше, обновления также могут быть перезапущены с помощью приложения карты (или любого другого аналогичного средства).

Мой обходной путь заключается в следующем: всякий раз, когда я останавливаю одного менеджера, я также сбрасываю фильтры расстояния всех остальных (хранящихся вNSSet называется myCLLocationManagers), как показано ниже:

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

Кажется, это работает более надежно, чем мой предыдущий глобус (который должен был останавливать и перезапускать менеджеры).

Примечаниечто kCLLocationAccuracyBestForNavigation и kCLLocationAccuracyBest являются (в настоящее время) отрицательными значениями, и что в целом вы не должны полагаться на указанныеc значения всех этих констант - нет гарантии, что kCLLocationAccuracyHundredMeters==100 (хотя в настоящее время верно).Я упоминаю об этом только потому, что кажется, что вы напрямую сравниваете переменную «точность» в метрах с этими константами.

...