iOS 4 在应用程序处于后台时使用 GPS 定期更新位置
是否可以让手机每隔 30 分钟启动一次 GPS,并在应用程序处于后台状态时获取用户的位置?
重要的位置变更服务对于我的需求来说有点太不精确了。
我试图始终跟踪手机,而又不会过多地消耗电池寿命。任何建议都非常受欢迎!
Is it possible to have the phone power up the GPS every say 30 minutes and get the user's location while the app is in a background state?
The significant location change service is a little too unprecise for my needs.
I am trying to track a phone at all times without killing the battery life too much. Any suggestions are more than welcome!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我知道这已经“晚了”,但据我所知,这仍然是一个问题(一直在寻找解决方案 - 如果最近有更改,请发布)...
不幸的是,这里的回复涵盖了大部分基础,但是我的经验可能会有些帮助。使用 VOIP 标志允许您的应用程序定期唤醒并进行一些处理(例如 GPS)效果很好,但 Apple 审查不允许这样做,除非您实际上正在使用 VOIP。我们在 AppStore 中有一个应用程序可以实现这个功能。它工作得非常好——非常低的电池消耗,完美的 GPS 跟踪。经过几次更新后,一些聪明的审阅者(现在可能是自动检查)识别了该标志,但我们并没有真正使用 voip 并拒绝了该应用程序。自从我们刚刚关闭后台 GPS 跟踪以来,当电池寿命下降到 90 分钟且 GPS 持续消耗时,我们就没有太多选择了。
与此相关的其他评论是为什么定时 GPS 收集在不在调试器中运行时在后台死亡的原因 - 它死亡是因为活动线程停止或过期(如果您已经购买了一些时间来完成某些任务),并且没有办法根据内部计时器恢复任何后台活动。某种定期通知可能会起作用(我将尝试这种方法),或者最坏的情况是定期推送通知......但它可能没有足够的时间来获取和报告准确的 GPS 位置,所以你会一次再次处于保持 GPS 运行的位置。我们的应用程序有一个“强制后台 GPS”模式,该模式仅在设备插入电源时使用,因此不会消耗电池,但这是迄今为止我们想到的最好的模式。
绝对最糟糕的情况(几乎忘记了这个)是重大变化选项的唤醒,但这已被证明既不准确又相距甚远(是的,几英里很重要,但对于真正的跟踪有什么好处)。
定期唤醒方法效果非常好,并且到目前为止符合用户的最大利益(节省电池),令我惊讶的是苹果不允许它用于此目的。对基于位置的应用程序的支持存在重大疏忽。
I know this is "late", but since this is still an issue as far as I know (always looking for a fix - if there is a recent change please post)...
The responses here cover most of the bases unfortunately, but my experience might be somewhat helpful. Using the VOIP flag to allow your app to wakeup at intervals and do some processing (like GPS) works great, BUT Apple review won't allow it unless you are in fact using VOIP. We had an app in the AppStore that did this trick. It worked beautifully - very low batter consumption, perfect GPS tracking. After a couple of updates some smartass reviewer (probably an automated check now) recognized the flag but that we were not really using voip and rejected the app. Ever since we had just turned of background GPS tracking - not much choice when battery life drops to 90 minutes with constant GPS burn.
The other comment related this was why the timed GPS collection dies in the background when not running in a debugger - it dies because the active threads stop or expire (if you have bought some time to complete some tasks),and there is no way to resurrect any background activity based on an internal timer. Some sort of periodic notification might work (I'm going to try that approach) or worst case a periodic push notification... but it probably does not buy enough time to get and report an accurate GPS location, so you'd be once again in a position to leave the GPS running. Our app has a "force background GPS" mode that is intended to be used only when the device is plugged in so there is no battery drain, but that's the best we have figured out so far.
The absolute worst case (almost forgot this one) is the wake on significant change option, but that has been shown to be both inaccurate and much to far apart (yeah, a couple miles is significant but what good is that for real tracking).
The periodic wakeup approach worked so well, and was in the best interest of the user by far (to conserve battery) that I was flabbergasted that Apple did not allow it for this purpose. A major oversight in support for location based apps.
苹果只给你两个选择,这恰好是两个极端:
Apple only gives you two options, which happen to be two extremes:
我有一个非常相似的要求:我的应用程序应该定期(通常为 1 分钟)拍摄高度准确的位置快照,即使设备正在睡眠或应用程序在后台,它也必须这样做。
为了在前台实现这一目标,我实现了一个系统,该系统打开定位服务,等待达到所需精度的位置,然后关闭服务,直到计时器触发。这个过程会重复进行,并且似乎按预期工作:在收到准确的位置读数之前,会返回六个不准确的位置读数(在几秒钟的时间内)。
测试表明,这种方法在设备睡眠时有效,这让我感到惊讶!所以现在我们只需要担心应用程序何时进入后台。
以下是我用来将其扩展到后台数据收集的机制:
设置 info.plist 值以指示应用程序需要位置更新,即使不在前台也是如此。 Apple SDK 文档的“跟踪用户位置”部分对此进行了记录。它保证即使在后台或睡眠状态下,位置更新也会传递到应用程序。
然而,这种方法不允许(开箱即用)定期收集,而是每当位置服务发现所需精度值定义的位置变化时就会发送通知。
不幸的是,如果您在应用程序后台运行后关闭位置服务数据收集,它将不再收到通知(应用程序位于后台,还记得吗?)。因此,我正在探索在 UIApplication 上使用 setKeepAliveTimeout:handle 方法来进行定期检查,从而有效地替换我的前台计时器。 [注意 - 要注册 KeepAlive 处理程序,您还必须设置 info.plist 以指示应用程序正在执行 VOIP] 当调用 KeepAlive 处理程序时,它会在处理程序中打开位置服务,收集数据,然后关闭位置服务。测试表明,这确实会重新启动位置服务通知。但我看到 KeepAlive 处理程序仅每隔 10 分钟(600 秒)被调用一次,我不确定这是否足够好。
请注意,setKeepAliveTimeout:handle 方法适用于 VOIP 应用程序,显然 Apple 非常仔细地检查了使用它的应用程序。就我而言,这是一个针对使用 Wireless Distribution 的客户的应用程序,而不是 Apple 商店的应用程序,所以这对我来说不是问题。
然而,如果这种方法有效,它似乎可以满足 Apple API 无法满足的需求:平衡对高精度位置数据的需求,同时仅定期收集该数据以节省电池寿命。苹果确实应该支持定时收集模型,而不仅仅是基于准确性。啊,好吧!
干杯
I have a very similar requirement: my app is supposed to take highly accurate location snapshots at a periodic interval (typically 1 minute) and it has to do so even if the device is sleeping or the app is in the background.
To accomplish this in the foreground I implemented a system which turns on the location service, waits for a location of the desired accuracy, then shuts off the service until a timer fires. This process repeats and seems to work as expected: half a dozen inaccurate location readings are returned (in the space of a few seconds) before an accurate one is received.
Testing has shown that this approach WILL work when the device is sleeping, which surprised me! So now we just have to worry about when the app is backgrounded.
Here is the mechanism I am using to extend this to data collection while in the background:
Set the info.plist value to indicate that location updates are needed by the app, even when not in the foreground. This is documented in the "Tracking The User's Location" section of the Apple SDK docs. It guarantees that location updates will be delivered to the app even in the background, or sleeping.
However, this approach doesn't allow (out of the box) a periodic collection, but, instead notices are sent whenever the location services see a location change as defined by the desired accuracy value.
Unfortunately, if you turn off location services data collection after the app is backgrounded it no longer receives notices (the app is in the background, remember?). So I'm exploring using the setKeepAliveTimeout:handle method on UIApplication to ALSO do a periodic check, effectively replacing my foreground timer. [Note -- to register the KeepAlive handler you also have to set the info.plist to indicate the app is doing VOIP] When the KeepAlive handler gets called it turns on location services in the handler, gather data, then turn off the location services. Testing has shown that this DOES re-start the location services notifications. But I'm seeing the KeepAlive handler only getting called at 10 minute intervals (600 seconds) and I'm not sure if that is good enough.
Note that the setKeepAliveTimeout:handle method is intended for VOIP applications, and apparently Apple examines apps that use it VERY closely. In my case this is an app for a client who uses Wireless Distribution, not the Apple store, so it isn't an issue for me.
However, if this approach works it seems to satisfy a need not met by the Apple API: balancing the need for highly accurate location data, while only collecting that data at intervals to conserve battery life. Apple really should support a timed collection model, and not just based on accuracy. Ah, well!
Cheers