应用终止后接收位置更新 [英] recieving location updates after app is terminated

查看:78
本文介绍了应用终止后接收位置更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一直保持用户位置(但不要耗尽电池)。
我了解在应用终止后获取更新的唯一方法是使用startMonitoringSignificantLocationChanges。

I need to keep track of the user location all the time (but not drain the battery). I understand the only way to get updates after app is terminated is using startMonitoringSignificantLocationChanges.

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

From Apple's Location Awareness Programming Guide on startMonitoringSignificantLocationChanges:


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

如果有人可以在代码中演示(举个例子),我会很高兴。

I would be glad if someone could demonstrate in the code (give an example) which methods i should use

我要转到的代码:
-在appdelegate中启动位置管理器,该管理器会对主要监视器进行更改,更新和启动日期。
-在didUpdateToLocation中,当我检查是否有UIApplicationLaunchOptionsLocationKey以便知道我是否在后台并由于监视器位置更新而启动时,我在didFinishLaunchingWithOptions中调用stopbdating
-在didFinishLaunchingWithOptions中。
-如果是这样,我再次调用startMonitoringSignificantLocationChanges(不确定为什么...)
并开始UIBackgeoundTaskIdentifier来调用startupdating方法。

In the following code i'm tring to : - start the location manager at appdelegate which strats the signinficant monitor changes update and startupdating. - in didUpdateToLocation i'm calling stopupdating - in didFinishLaunchingWithOptions when i check if i got a UIApplicationLaunchOptionsLocationKey in order to know if i'm in the background and launched due to siginificant monitor location update. - if so, i call startMonitoringSignificantLocationChanges again (not sure why...) and begin a UIBackgeoundTaskIdentifier for calling startupdating method.

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");
}

谢谢。

推荐答案

使用类,这就是我要做的。

Using your classes, this is what I would do.

在AppDelegate.m中,当您的应用程序位于前景或背景,我将CLLocationManager移动到在前景/背景中运行以进行匹配。我这样做的原因是因为如果应用程序在后台时CLLocationManager没有移到后台,则不会将位置更新发送到CLLocationManager的回调

In your AppDelegate.m, when your app is in the foreground or background, I'd move the CLLocationManager to run in the foreground / background to match. The reason I'm doing this is because if the CLLocationManager is not moved to the background when the app is in the background, no location updates are sent to the CLLocationManager's callback

- (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决定它使用了过多的内存并杀死了您的应用程序。

So lets say your app then moves to the background, and after awhile, iOS decides it's using too much memory and kills your app.

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

A few minutes later, iOS then receives a location update, and respawns your app, letting it know it respawned due to a location service. You then need to re-start the background location service, as it will be the only chance your app has to do so.

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

哦,还有最后一个更改,我不确定为什么在您的 locationManager:didUpdateToLocation:fromLocation:方法正在停止位置服务,因为这样做时不再进行更新。只需使其运行,然后每次位置更改发生时,您都可以将其发送到服务器。

Oh, and one last change, I'm not sure why in your locationManager:didUpdateToLocation:fromLocation: method you're stopping the location service, as when you do that no more updates come through. Just leave it running, then every time a location change comes through you can send that to the server.

- (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

}

这篇关于应用终止后接收位置更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆