iPhone后台GPS暂停后无法恢复定位问题

29

我的应用程序需要在后台跟踪用户位置的变化,只要用户在移动,它就可以正常工作。 当用户停止行动并且CLLocationManager暂停10-20分钟左右时,会发出以下通知:

-(void)locationManagerDidPauseLocationUpdates:(CLLocationManager *)manager{}

这对我来说也没问题。很好,可以省电等等。

问题是当用户重新开始移动时,CLLocationManager从不醒来,而且直到我将应用程序放到前台(变为活动状态),以下委托方法永远不会被触发

//Never called back after CLLocationManager pauses:
-(void)locationManagerDidResumeLocationUpdates:(CLLocationManager *)manager{}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{}

设备重新开始移动后为什么locationManagerDidResumeLocationUpdates没有被调用?难道GPS不应该自动恢复(因为已经自动暂停了)吗? 是否有一种方法可以在没有用户交互的情况下恢复GPS?

应用程序在Info.plist文件中声明了以下内容:

enter image description here

我的CLLocationManager设置如下:

locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager setActivityType:CLActivityTypeFitness];
//I WANT pauses to save some battery, etc... That is why following line is commented out (default)
 //[locationManager setPausesLocationUpdatesAutomatically:NO];
 locationManager.distanceFilter = kCLLocationAccuracyNearestTenMeters;
 locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
 [locationManager startUpdatingLocation];

问题是,如果您一次性获取背景和前景之间的所有位置(即获取位置列表)。 - AlexWien
因此,pausesLocationUpdatesAutomatically属性很可能是原因。当您进入后台时,可以尝试将其设置为false,并在进入前台时将其设置为true。 - AlexWien
4
这不是解决方案。我想要暂停工作。文档说明当用户再次开始移动时应调用“resume”函数。我想知道为什么没有调用。 - Lukasz
我更新了链接到SO和苹果推荐。 - AlexWien
1
我的问题不是关于 pausesLocationUpdatesAutomatically 属性的作用。我理解这个函数。我的问题主要是关于恢复 GPS 的问题。我需要确切地知道是否暂停是确定的,或者 GPS 是否可以自动恢复。当我完成对此的研究并证明您是正确的时候,我当然会接受这个答案。 - Lukasz
显示剩余6条评论
3个回答

31
如果您在苹果论坛上搜索pausesLocationUpdatesAutomatically,您会找到一个类似的问题,并得到苹果开发人员的回复。我不会在此直接转载,因为这是一个私人论坛,但要点是当用户忘记他们正在运行具有位置感知功能的应用程序并停止使用它时,位置暂停就会发生。通过暂停更新,可以减少电池的消耗。遗憾的是,无法确定新的移动是否是恢复活动还是做其他事情,因此更新直到应用程序返回前台才能恢复。他们的建议是“捕捉”暂停调用,并以某种方式吸引用户的注意力,以便他们打开应用程序(如果他们仍然想要更新)。
编辑:从苹果对

pausesLocationUpdatesAutomatically的文档中可以了解到,他们建议:

在暂停后,您需要负责在确定需要时重新启动位置服务。Core Location调用您的位置管理器的委托的locationManagerDidPauseLocationUpdates(_:)方法,让您知道暂停已发生。在该方法中,您可能会配置一个本地通知,其触发器类型为UNLocationNotificationTrigger,并设置为在用户退出当前区域时通知。本地通知的消息应提示用户再次启动您的应用程序,以便它可以恢复更新。


6
我尝试寻找你所提到的论坛讨论,但是我没有找到。您能否发一个链接?谢谢! - Steven Wexler
我也对这个讨论感兴趣。 - lostintranslation
这里有一些内容。有人在苹果论坛上找到了讨论这个问题的帖子吗? - Stephen Johnson
3
没有开玩笑。它应该被称为:locationManager被终止而不是暂停,应用程序当前将被挂起,因此您无法继续实时更新,您必须使用其他选项。暂停意味着可以恢复,但在这里没有恢复的能力。 - mfaani
从我的了解来看,只有在你处于前台暂停状态时才能重新启动。如果你在后台并且你的位置已经被暂停,那么应用程序将被挂起。之后重新开始位置跟踪的唯一方法是再次启动应用程序,然后启动位置跟踪。 - mfaani

3
苹果文档在这个主题上非常薄弱。属性pausesLocationUpdatesAutomatically允许苹果在用户不需要GPS时关闭GPS。虽然没有记录,但设置此属性似乎会导致后台模式下GPS停止工作。多篇文章描述了该属性的问题:例如,这里:
iOS 6 CoreLocation does not work。在 iOS 6 AutoPause doesn't work 中,Stanislav Dvoychenko发表了苹果公司的建议:

[更新-2013年3月4日]。我查看了苹果公司有关iOS6位置更改的演示,并建议使用区域更改监控来“取消暂停”,一旦您收到区域更改事件。尽管在我的情况下,这并不适用,因为用户可能会走/跑/开车一公里或两公里,直到出现这种事件。

我建议将该属性设置为false。

2
这是唯一的解决方案吗?我感觉苹果设计他们的委托在非对称的方式下有些奇怪。委托的暂停回调应该通过恢复来平衡,而不引入任何额外的设置。也许activityType可能会对此产生影响。 - Lukasz
2
可能更多是技术原因,而不是委托设计。如果 GPS 关闭,您无法可靠地检测移动:要么通过 GSM 小区变化(1000 米精度),要么通过 WiFi(如果附近有一些 WiFi 热点)。或者使用加速度传感器:当设备被硬安装时,可以用于车辆。但对于行人来说不起作用。如果您在餐厅坐着时在座位上移动,这很难与健身相关的运动区分开来。 - AlexWien
你的意思是在locationmanagerdidpauselocationupdates回调函数内执行startUpdateLocations会静默失败吗? - mfaani

1
如果可能的话,请使用startMonitoringSignificantLocationChanges,因为这样(苹果公司):
如果您启动此服务并且随后终止应用程序,则系统会在发生新事件时自动将应用程序重新启动到后台。
您可以尝试在应用程序唤醒后结合更精细的跟踪(例如用户重新进入应用程序)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接