在后台和暂停的应用模式下更新位置 [英] Location update in background and suspended app modes

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

问题描述

我想编写应用程序,每5分钟发送到服务器低精度位置的两种模式:前景和后台。因为我不想减少电池电量而且locationSignificantChange只给出高精度值,所以我每隔5分钟从GPS启动/停止位置更新。应用程序在前台模式下工作正常,但从后台模式起作用仅约1小时(之后停止发送位置)。我想我在backgroundTask / NSTimer代码中遗漏了一些东西,因为我是iOS的新手。我将非常感谢你的帮助。该应用程序仅适用于iOS 7及更高版本。

I want to write application that every 5 min sends to server low-accuracy-location for its both modes: foreground and background. Because I don't want to reduce the battery charge and the locationSignificantChange gives only the high-accuracy-values, I start/stop locationUpdates from GPS every 5 min. Application works fine from foreground mode, but works only about 1 hour from background mode (and stops to send location afterwards). I guess I am missing something in backgroundTask/NSTimer code because I am new with iOS. I will very appreciate your help. The application will be only for iOS 7 and up.

一般来说,我的算法如下:

In general my algorithm is follow:

** start backGroundTask
** [_locationManager startUpdatingLocation]
** handle received location in "didUpdateLocations:" listener
** [_locationManager stopUpdatingLocation]
** create new thread and fire the NSTimer with delay 5 min
** end backGroundTask

这是我的代码:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        [self startLocationManager];
        // .. other init app code
}



- (void) startLocationManager {
          _locationManager = [[CLLocationManager alloc] init];
          _locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
          _locationManager.distanceFilter = 10;
          _locationManager.delegate = self;
          _locationManager.pausesLocationUpdatesAutomatically = NO;
          [_locationManager startLocation];
}



- (void) startLocation {
    UIApplication * app = [UIApplication sharedApplication];
    self.bkgdTask = [app beginBackgroundTaskWithExpirationHandler:^{
    }];
    [self.locationManager startUpdatingLocation];
}



- (void) stopUpdatingLocation {

    [_locationManager stopUpdatingLocation];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
       self.locationNextTimer =  [NSTimer scheduledTimerWithTimeInterval:5 * 60
                                                                 target:self
                                                                 selector:@selector(startLocation)
                                                                 userInfo:nil
                                                                 repeats:NO];
        [[NSRunLoop currentRunLoop] addTimer:self.locationNextTimer forMode:NSDefaultRunLoopMode];
        [[NSRunLoop currentRunLoop] run];
        [app endBackgroundTask:self.bkgdTask];
        self.bkgdTask = UIBackgroundTaskInvalid;
     });
}



- (void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
       [self.locationNextTimer invalidate];
       self.locationNextTimer = nil;
       //ToDo  Location Handling
       [self stopUpdatingLocation];
}



编辑:



据我所知,从iOS7开始,Apple希望locationManager的startUpdatingLocation只能从前台完成。那么解决这个问题的任何想法呢?
我还尝试了其他解决方案:使用NSTimer来停止/ startUpdatingLocation,使用NSTimer更改大/小值的准确度和distanceFilter。它没有用,因为我在didUpdateLocations:监听器中接收了4次高速公路驾驶而不是一次。

As I understood from iOS7 Apple wants that startUpdatingLocation for locationManager will be done only from foreground. So any ideas for solution of this problem? I also tried additional solution: instead stop/startUpdatingLocation with NSTimer, to change the accuracy and distanceFilter for big/small values with NSTimer. It did not work because I receive trigger in "didUpdateLocations:" listener 4 times for "freeway drive" instead of one time.

推荐答案

位置管理员将根据您的设置自行决定最少的活动。根据您的使用情况设置适当的参数,然后在您的代理中负责任地行事。测试收到的位置,如果它们太近,那么你什么都不做。这将允许您的应用处理尽可能少地影响电池。

The location manager will decide for itself the least activity based on your settings. Set the parameters as appropriate for your use case then act responsibly in your delegate. Test the locations received, if they are too recent then you do nothing. This will allow your app processing to impact battery as little as necessary.

significantLocationChanges 旨在减少影响,根据我的经验,它做得很好。另一种选择是使用区域监控来代替或同时使用。

significantLocationChanges is meant to reduce impact and, in my experience, does a pretty good job of it. Another option is to use region monitoring instead or along with.

您可以通过根据您希望达到的准确度创建大小的区域来进一步限制活动。仅在跨越边界时更新区域并保存位置。这可能更适合您的需求。

You can further limit activity by creating regions of a size based on the accuracy you wish to achieve. Update regions and save location only as boundaries are crossed. This may be more appropriate for your needs.

这篇关于在后台和暂停的应用模式下更新位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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