2012-02-16 105 views
1

我正在處理定期獲取用戶位置的應用程序。最大的問題是,有時應用程序卡住了,沒有更多的更新傳遞。即使我(殺死和)重新啓動我的應用程序,沒有任何變化。 (爲位置管理器設置的精度值接近100-200米。) 但是,當我啓動Google地圖應用程序時,幾秒鐘內就會得到一個非常準確的位置(如果我切換回來,它會傳送到我的應用程序) 。爲什麼? 以下是一些相關的代碼部分:CLLocationmanager有時卡住

定時器週期性地調用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] ; 

    } 

} 

的啓動和停止方法簡單verifiy如果是的LocationManager爲零,如果是他們叫createManager,然後調用啓動& 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; 
    } 
} 

這兒還有沒有人經歷過這樣的事情?任何想法都歡迎:) 謝謝!

+0

我對被解僱的行爲有些困惑。你爲什麼想這樣做?有(void)locationManager:(CLLocationManager *)經理\t didFailWithError:(NSError *)錯誤發生時,然後重新啓動您的CLManager。這比定期檢查狀態好多了(我認爲這是你的方法) – Yorxxx 2012-02-16 11:59:59

+0

我也使用該方法,但僅用於監視錯誤。當定時器更新成功後觸發定時器,它將設置等待標誌。它可以在不獲得更新的情況下多次觸發(例如每3秒),在這種情況下,我不需要啓動位置管理器,並且該標誌指示它現在正在更新/定位。 – Templar 2012-02-16 13:06:52

回答

0

我至少可以確認「阻塞位置經理人」,但在一個稍微不同的背景:

從我的經驗,如果您創建兩個位置經理不同精度設置,啓動了兩個更新,然後才能停止更新對於精度要求較高的那個,那麼另一個不再接收任何更新。

您顯然只使用一位經理,但您的經理卡住的方式似乎是相同的:在上述情況下,更新也可以使用地圖應用程序(或任何類似)重新啓動。

我的解決方法是:每當我停止一個經理,我也重置所有其他人的距離過濾器(存儲在一個名爲myCLLocationManagersNSSet),如下所示:

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

這似乎是工作更可靠地比我以前的工作(這是停止和重新啓動經理)。

注意kCLLocationAccuracyBestForNavigationkCLLocationAccuracyBest是(目前)負值,而在一般情況下,你不應該依賴於所有這些常量的具體數值 - 有沒有保證kCLLocationAccuracyHundredMeters==100(雖然目前如此)。我只提到這一點,因爲它看起來像是直接比較米的「精度」變量和那些常數。

+0

最初我有兩個經理,一個是GPS,一個是Sig,我認爲這是問題的原因,但似乎沒有。此代碼僅適用於一個實例。 – Templar 2012-02-17 07:04:52

+0

強制方法(停止&開始)有時可以幫助,有時不會,這很奇怪。關於準確性,我知道他們是負面的,我不應該直接比較,但對於積極的準確性,它是可比的(在我的情況下,他們是〜100-200)。無論如何,我在打印完位置後檢查代理的準確性,但是當應用程序卡住時,代理根本不會被調用。 – Templar 2012-02-17 07:13:11