2012-06-11 65 views
4

我需要始終跟蹤用戶位置(但不會耗盡電池)。 我明白應用程序終止後獲取更新的唯一方法是使用startMonitoringSignificantLocationChanges。應用程序終止後接收位置更新

從蘋果的位置感知編程指南startMonitoringSignificantLocationChanges:

如果啓動該服務,並且您的應用程序隨後 終止,如果一個新的事件到達時,系統會自動將重新啓動應用程序到 背景。在這種情況下,選擇 字典傳遞到應用程序中:didFinishLaunchingWithOptions:您的應用程序委託的 方法中包含的關鍵 UIApplicationLaunchOptionsLocationKey以表明您 應用程序是因爲定位事件的啓動。 重新啓動後,您仍然必須配置一個位置管理器對象,並調用此方法繼續接收位置事件。當您重新啓動 位置服務時,當前事件將立即傳送到您的代理 。此外,在開始位置服務之前,您的位置 管理員對象的位置屬性將使用最新的位置對象(即使是 )填充。

我會很高興,如果有人可以在代碼演示了(舉個例子),這方法我應該使用

在下面的代碼我我特林: - 啓動在的appdelegate位置管理器這使得重要的監視器更改更新和啓動更新。 - 在didUpdateToLocation我打電話stopupdating - 在didFinishLaunchingWithOptions當我檢查是否有一個UIApplicationLaunchOptionsLocationKey爲了知道我是否在後臺,並啓動由於siginificant監視器位置更新。 - 如果是這樣,我再次調用startMonitoringSignificantLocationChanges(不知道爲什麼...) 並開始一個UIBackgeoundTaskIdentifier來調用startupdating方法。

LocationController.m : 
+ (LocationController*)sharedInstance { 
    @synchronized(self) { 
     if (sharedCLDelegate == nil) { 
      [[self alloc] init]; 
     } 
    } 
    return sharedCLDelegate; 
} 

- (id)init 
{ 
    self = [super init]; 
    if (self != nil) { 
     self.locationManager = [[[CLLocationManager alloc] init] autorelease]; 
     self.locationManager.delegate = self; 
     self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters; 
     [self.locationManager startUpdatingLocation]; 
     [self.locationManager startMonitoringSignificantLocationChanges]; 

    } 
    return self; 
} 
- (void) startMonitoringSignificantLocationChanges 
{ 
    [self.locationManager startMonitoringSignificantLocationChanges]; 
} 
- (void) stopMonitoringSignificantLocationChanges 
{ 
    [self.locationManager stopMonitoringSignificantLocationChanges]; 
} 
-(void) start{ 
    [self.locationManager startUpdatingLocation]; 
} 
- (void)locationManager:(CLLocationManager *)manager 
    didUpdateToLocation:(CLLocation *)newLocation 
      fromLocation:(CLLocation *)oldLocation{ 
    if (abs([newLocation.timestamp timeIntervalSinceDate: [NSDate date]]) < 30) { 
     self.lastLocation = newLocation; 
     [self updateLocation]; //sending location to server 
     [self.locationManager stopUpdatingLocation]; 
    } 
} 
- (void)locationManager:(CLLocationManager*)manager 
     didFailWithError:(NSError*)error{ 
    [self.locationManager stopUpdatingLocation]; 
} 

AppDelegate.h : 

@interface AppDelegate : NSObject <UIApplicationDelegate> { 
    UIBackgroundTaskIdentifier bgTask; 
} 

AppDelegate.m : 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
     id locationValue = [launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]; 
     if (locationValue) { 
      [[LocationController sharedInstance] startMonitoringSignificantLocationChanges]; 
      UIApplication *app = [UIApplication sharedApplication]; 
      bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ 
       [app endBackgroundTask:bgTask]; 
       bgTask = UIBackgroundTaskInvalid; 
      }]; 
      [[LocationController sharedInstance] start]; //startupdating 
      return YES; 
     } 
    else { 
      [[LocationController sharedInstance] init]; 
    } 
} 
-(void) applicationDidEnterBackground:(UIApplication *) application 
{ 
    NSLog(@"entered background Mode"); 
} 

-(void) applicationDidBecomeActive:(UIApplication *) application 
{ 
    NSLog(@"application Did Become Active"); 
} 

謝謝。

回答

11

使用你的課程,這是我會做的。

在您的AppDelegate.m中,當您的應用處於前景或背景中時,我會移動CLLocationManager以在前景/背景中運行以匹配。我這樣做的原因是因爲如果CLLocationManager沒有移動到後臺時,應用程序在後臺運行,沒有位置更新發送到CLLocationManager的回調

- (void)applicationDidEnterBackground:(UIApplication *) application { 
    [[LocationController sharedInstance] stop]; 
    [[LocationController sharedInstance] startMonitoringSignificantLocationChanges]; 
    NSLog(@"entered background Mode"); 
} 

- (void)applicationDidBecomeActive:(UIApplication *) application { 
    [[LocationController sharedInstance] stopMonitoringSignificantLocationChanges]; 
    [[LocationController sharedInstance] start]; 
    NSLog(@"application Did Become Active"); 
} 

因此,可以說您的應用程序,然後移動到背景,過了一段時間,iOS決定使用太多內存並殺死你的應用程序。

幾分鐘後,iOS會收到一個位置更新,然後重新啓動您的應用程序,讓它知道它由於位置服務而重新生成。然後您需要重新啓動後臺位置服務,因爲這將是您的應用必須這樣做的唯一機會。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) { 
     [[LocationController sharedInstance] startMonitoringSignificantLocationChanges]; 
    } 
    return YES; 
} 

哦,最後一個變化,我不知道爲什麼在你的locationManager:didUpdateToLocation:fromLocation:方法你停止位置服務,當你這樣做沒有更多的更新來通過的。只需讓它繼續運行,然後每次發生位置更改時都可以將其發送到服務器。

- (void)locationManager:(CLLocationManager *)manager 
    didUpdateToLocation:(CLLocation *)newLocation 
      fromLocation:(CLLocation *)oldLocation { 

    if (abs([newLocation.timestamp timeIntervalSinceDate: [NSDate date]]) < 30) { 
     self.lastLocation = newLocation; 
     [self updateLocation]; //sending location to server 

} 
+1

我想看到的這個記錄在蘋果的文檔 – hariszaman

相關問題