应用程序终止后收到位置更新

Lia*_*atz 5 cllocationmanager cllocation

我需要一直跟踪用户位置(但不要耗尽电池).我理解终止应用程序后获取更新的唯一方法是使用startMonitoringSignificantLocationChanges.

从关于startMonitoringSignificantLocationChanges的Apple位置感知编程指南:

如果您启动此服务并且您的应用程序随后终止,则系统会在新事件到达时自动将应用程序重新启动到后台.在这种情况下,传递给应用程序的选项字典:didFinishLaunchingWithOptions:应用程序委托的方法包含密钥UIApplicationLaunchOptionsLocationKey,以指示您的应用程序是由于位置事件而启动的.重新启动后,您仍必须配置位置管理器对象并调用此方法以继续接收位置事件.重新启动位置服务时,会立即将当前事件传递给您的代理.此外,即使在启动位置服务之前,也会使用最新的位置对象填充位置管理器对象的位置属性.

如果有人可以在代码中演示(举例)我应该使用哪种方法,我会很高兴

在下面的代码中,我要说: - 在appdelegate启动位置管理器,它可以监控signinficant监视器更改更新和启动日期. - 在didUpdateToLocation中我正在调用stopupdating - 在didFinishLaunchingWithOptions中,当我检查我是否有UIApplicationLaunchOptionsLocationKey以便知道我是否在后台并且由于显着的监视器位置更新而启动. - 如果是这样,我再次调用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");
}
Run Code Online (Sandbox Code Playgroud)

谢谢.

jkl*_*klp 10

使用你的课程,这就是我要做的.

在您的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");
}
Run Code Online (Sandbox Code Playgroud)

因此,假设您的应用程序移动到后台,过了一段时间,iOS决定使用太多内存并杀死您的应用程序.

几分钟后,iOS接收位置更新,并重新生成您的应用程序,让它知道由于位置服务而重新生成.然后,您需要重新启动后台位置服务,因为这将是您的应用程序必须这样做的唯一机会.

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

哦,还有最后一次更改,我不确定为什么在你的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

}
Run Code Online (Sandbox Code Playgroud)