fmc*_*fmc 38 power-management core-location cllocationmanager ios core-bluetooth
我们已经发布了一个在后台运行的应用程序,并使用CoreBluetooth&CoreLocation自动保存您的停车位置.
在较高的水平,我们的应用程序只是寻找CoreBluetooth断开连接事件并打开GPS,直到我们得到一个位置修复(准确度<= 10米)或最多3分钟(这可能发生在你没有GPS覆盖的地下停车场停车) .然后,我们使用重要位置监控在系统终止我们的应用程序时自动重新启动我们的应用程序.
在我们的开发过程中,我们自己从未看到过电池耗尽问题,但是75%的用户表示他们看到电池消耗很大.10%的支持者回应了民意调查,因此很难确定故障的代表性,但我们的用户占很大比例.http://www.findmycarsmarter.com/forum/viewtopic.php?f=4&t=30
然后,我们发布了一项更新,允许用户禁用重要位置监控,60%的人表示,通过禁用重要位置监控,排放消失.http://www.findmycarsmarter.com/forum/viewtopic.php?f=4&t=42
最初我们不能自己复制排水问题,但我们发现当我们安装了一个简单的应用程序,只需将"重要位置监控"与"查找我的汽车智能"结合使用时,我们就会间歇性地看到排水管重现.在排水状态下,手机不会进入休眠状态.这表示即使手机已进入睡眠状态且显示屏已关闭,(设置 - >使用 - >自上次完全充电以来的时间)的使用时间也会继续增加.有些东西会阻止系统进入休眠状态.在这个阶段,电池每小时消耗约15%.这种排水间歇地出现,似乎在一两个小时后自行消失,然后再次随机出现.我们还没有找到一种可靠性来重现排水的方法.
我们认为问题是由多个客户调用CoreLocation引起的.我们询问了一些遇到此问题的用户擦拭手机并只安装了我的Find My Car Smarter应用程序.只安装了这个应用程序,排水管没有展出.我们还有其他报告称,当我们的应用与谷歌纵横或Facebook等一起使用时,他们会看到流失.或者如果他们去杀死其他应用程序,那么排水管就会消失.我们已经看到,在没有应用程序启动的情况下,耗电会持续通过电源循环.这意味着它必须是一个系统级服务,以防止操作系统休眠.
尽管我们认为问题是由多个客户端调用到CoreLocation的一些竞争条件引起的,我们从来没有见过的问题与应用程序,只用CoreLocation重现.我们甚至创建了4个或5个不同的应用程序,这些应用程序将同时访问CoreLocation,我们没有看到排放发生.然而,当我们有一个带有CoreLocation的应用程序和带有CoreLocation + CoreBluetooth的第二个应用程序时,我们确实看到了这个问题.可能很少有应用程序使用CoreLocation + CoreBluetooth组合,所以可能这就是为什么更多的开发人员没有遇到这个问题.虽然我们无法解释CoreLocation和CoreBluetooth如何相互作用导致这种消耗以及CoreLocation的第二个应用程序如何进入这个等式.由于排水是间歇性的,所以这可能只是一个侥幸,这个问题只发生在我们使用CoreLocation + CoreBluetooth进行测试时.
在只有这两个应用程序CTM1和FMC安装的擦除5.0.1 iPhone 4S上,我们能够间歇性地进入排水状态.有趣的是,在我们的普通设备上,擦除设备上的排水问题似乎发生的频率要低得多.不幸的是,我们只看了几次排水状态而且没有能够可靠地再现排水管,我们没有良好的控制状态来工作.
我们已经向Apple提交了一份错误报告并开辟了技术支持事件,但也许Stackover社区也可以提供一些见解.我们在5.0.1和5.1 Beta 3中都看到了这个问题.
CTM1 http://www.findmycarsmarter.com/files/CTM1.zip
On Going into the Background
[locationManager stopUpdatingLocation];
[locationManager stopUpdatingHeading];
[locationManager startMonitoringSignificantLocationChanges];
On Re-entering Foreground
[locationManager stopMonitoringSignificantLocationChanges];
[locationManager startUpdatingLocation];
[locationManager startUpdatingHeading];
On didUpdateToLocation
//do nothing
On didUpdateHeading
//do nothing
Run Code Online (Sandbox Code Playgroud)
FMC http://www.findmycarsmarter.com/files/FMC.zip
On Going into the Background
[btleManager stopScan];
[locationManager stopUpdatingLocation];
[locationManager stopUpdatingHeading];
[locationManager startMonitoringSignificantLocationChanges];
On Re-entering Foreground
[locationManager stopMonitoringSignificantLocationChanges];
[locationManager startUpdatingLocation];
[locationManager startUpdatingHeading];
[btleManager scanForPeripheralsWithServices:nil options:nil];
On didUpdateToLocation
//do nothing
On didUpdateHeading
//do nothing
On centralManagerDidUpdateState
[btleManager scanForPeripheralsWithServices:nil options:nil];
On didDiscoverPeripheral
[btleManager connectPeripheral:device options:nil];
On didConnectPeripheral
//update log
On didDisconnectPeripheral
//initiate reconnect
[btleManager connectPeripheral:device options:nil];
Run Code Online (Sandbox Code Playgroud)
如果您发现可能导致排水的编码错误,请告诉我们.
我们确实有另一个问题,如果我们同时使用GPS和重要位置监控,是否有理由打电话stopMonitoringSignificantLocationChanges?看看他们调用stopMonitoringSignificantLocationChanges&startLocationUpdate进入前景和stopLocationUpdate&startMonitoringSignificantLocationChanges进入后台的区域示例代码,但我想知道这是否必要/推荐/需要?
更新:
我们已经证实了苹果开发者技术支持,同时使用GPS和显着的定位监测,我们的使GPS更新之前关闭显着位置监控的顺序是正确的应用程序.
我们还确认了排放问题仍然可以在GM 5.1中找到,并且针对5.1框架重新编译了Find My Car Smarter应用程序.
更新:
当我们的应用程序从后台启动以响应重要位置监视事件时,似乎会触发该问题.我们实际上没有在示例代码中正确处理这种情况,但我们在实际的应用程序中执行.
在示例代码中,在后台重新启动时,我们将打开位置更新,并且由于没有applicationDidEnterBackground呼叫,GPS将保持打开状态.
在我们的应用程序中,我们检查是否通过查找UIApplicationLaunchOptionsLocationKey标志从后台启动,如果是这样我们启动重要位置监控,否则我们在前台启动并开始更新位置.
Apple回复我们,并表示使用重要位置监控不需要在Info.plist中的UIBackgroundModes数组中设置位置.我们删除了此条目,似乎电池耗电状态不再受到影响.我们在UIBackgroundModes列表中仍然有蓝牙中心.目前我们还不清楚为什么这会有所帮助.我们将开展更多实验,以帮助我们更好地理解这一点.如果有人有任何建议,请告诉我们.
fmc*_*fmc 17
在一天结束时,Apple建议从UIBackgroundModes移除位置修复了我们的电池耗尽问题.
为了仍然在后台获取位置,我们必须用[locationManager startLocationUpdates]&包装&[locationManager stopLocationUpdates]调用:
[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler];
[[UIApplication sharedApplication] endBackgroundTask:];
Run Code Online (Sandbox Code Playgroud)