ios – 后台的StartUpdateLocations,didUpdatingToLocation只调用了10-20次

前端之家收集整理的这篇文章主要介绍了ios – 后台的StartUpdateLocations,didUpdatingToLocation只调用了10-20次前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
测试设备:iPhone 5(iOS 7)

我有一个使用RegionMonitoring和updateLocation的应用程序.如果输入某个区域,则会按预期调用didEnterRegion.然后我调用startUpdatingLocation.但是,方法didUpdateToLocation只被调用10-20次,而它应该更新位置,直到计时器触发.

相关代码

CLLocationManager *_locationManager;
NSTimer *_timer;

-(void)initLocationManager 
{
    _locationManager = [[CLLocationManager alloc] init];
    _locationManager.delegate = self;
    [_locationManager setActivityType:CLActivityTypeOther];
    [_locationManager setDesiredAccuracy:kCLLocationAccuracyBestForNavigation];
    [_locationManager setPausesLocationUpdatesAutomatically:NO];
    [_locationManager setDistanceFilter:kCLDistanceFilterNone];
}


//Did Enter Region,called as expected:
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    [_locationManager startUpdatingLocation];
    _timer = [NSTimer scheduledTimerWithTimeInterval:300.0f target:self selector:@selector(scheduleMethod:) userInfo:nil repeats:NO];
}


//Timer Fire Method:
- (void) scheduleMethod:(NSTimer*)timer
{
    [Utils writeToLog:@"Timer-Stop"];
    [_locationManager stopUpdatingLocation];
}


//This Method only called 10-20 Times (in the first 10-20 Seconds) and not the complete 5 Minutes:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
     [Utils writeToLog:@"LocationUpdate!"];
}

到目前为止我尝试过:
在locationManagerDidPauseLocationUpdates方法中重新启动更新,但似乎永远不会调用它:

-(void)locationManagerDidPauseLocationUpdates:(CLLocationManager *)manager
{
    [WRUtils writeToLog:@"LocationUpdate paused,restarted"];
    [_locationManager startUpdatingLocation];
}

检查didFailWithError方法中的错误,但是也没有调用它.
并且演奏了一些属性

[_locationManager setActivityType:CLActivityTypeOther];
[_locationManager setDesiredAccuracy:kCLLocationAccuracyBestForNavigation];
[_locationManager setPausesLocationUpdatesAutomatically:NO];

Plist设置是正确的我猜:
所需的背景模式是
所需的背景模式
项目0应用程序注册位置更新

我怎么解决这个问题?

解决方法

Apple已在iOS 7中引入了新策略.如果在应用程序处于后台调用“startUpdatingLocation”,iOS 7将不再在后台提供位置更新.在这种情况下,只有将应用程序带到前台才能获得更新.

当您使用地理围栏功能时,每次获得RegionEntered / Exited通知处理此通知时,您的应用程序只会获得几秒钟.在这几秒钟内,您还可以获得位置更新.在这几秒钟结束后,iOS 7再次暂停您的应用程序.

您可以使用后台任务获得超过几秒钟的时间,但在iOS 7中,Apple还将应用程序在后台运行的时间从10分钟(iOS 6及更早版本)减少到iOS 7下仅3分钟.看起来像这3分钟是应用程序在后台的总时间.这意味着你不能要求iOS 7 10次获得1分钟的背景时间,你总共只能得到3分钟,所以在第3次你要求一分钟后,你的应用程序将不再获得任何后台时间一点都不

您在后台获取位置更新的唯一机会是在App位于前台调用“startUpdatingLocation”.这很令人伤心,特别是当您只需要响应Region(进入/退出消息)的位置更新时,因为您需要让位置更新一直运行.但是您可以通过将准确度值设置为kCLLocationAccuracyThreeKilometers来减少电池使用量.
只有当您真正需要地理坐标时,才需要位置更新并将精度设置为kCLLocationAccuracyBest. iOS不会为GPS提供kCLLocationAccuracyThreeKilometers值,因此在这种情况下电池使用率会适中.

此外,精度值kCLLocationAccuracyBestForNavigation似乎在IOS 7下引起问题.如果设备未连接到外部电源,则不会使用此值进行任何位置更新.

总而言之,新的iOS 7位置更新政策使得开发某些类型的应用程序变得更加困难.您只需在应用程序的生命周期内注册这些内容,而不是仅在需要时注册位置更新.尽管苹果公司对这项新政策的意图可能恰恰相反,但这当然会让电池的耗电速度更快一些.

更新:

经过一些测试后,我找到了解决这个问题的方法.
Apple提供的文档提到,使用重要位置更改API时,即使在后台启动“startUpdatingLocation”,Apps也可以在后台接收位置更新.

我的第一次测试效果不佳.在调用startUpdatingLocation之前,我正在注册我的应用程序,以便在区域监视委托方法中进行重要的位置更新(因此仅在需要时启用此位置服务),但这仍然不会像文档建议的那样在后台提供位置更新.

但是,如果您在启动应用程序后直接开始侦听重要的位置更改(并且从不关闭它),则可以在应用程序处于后台调用start“startUpdatingLocation”,并在后台接收位置更新.一直具有“显着位置变化”功能的电池使用率似乎非常低,因此这可能是大多数应用程序的解决方案.

您必须检查设备上是否有“重要位置更改”功能,但似乎所有当前设备都支持功能.即便是第5代iPod Touch也支持它(iPod Touch不能使用手机信号塔进行位置更新,根据Apple的文档,这是此功能的基本方法,所以我想我们可以假设所有当前运行iOS的设备7可以使用“重要位置更新”API.虽然检查此功能是否真的可能是个好主意,但也许某些情况下该功能不可用).

使用“重要位置更改”API可能有一个缺点:应用程序可以在后台启动(如果它在后台由iOS终止,以便为其他应用程序重用其内存),无论何时设备已“显着移动” “(根据文档:当蜂窝塔已经改变,但每5分钟不超过一次).因此,只有当某个地区退出或进入时才需要激活的应用程序将被启动并通知位置已更改所有的时间,不仅仅是在那些地区.但我认为这应该比标准的位置更新始终更好.

我的iPhone 5s只消耗1%的电池,显着位置变化激活,而不是12%,标准位置更新激活,精度设置为3km.

希望这可以帮助所有正在努力应对新iOS 7行为的开发人员.

猜你在找的iOS相关文章