2012-06-11 63 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

相关问题