为了节省我的应用程序的功能,我决定在应用程序处于活动状态时使用startUpdatingLocation
混合,并在应用程序处于后台时进入startMonitoringSignificantLocationChanges
模式。当应用程序进入后台时,我基本上会执行以下操作:
-(void)applicationDidEnterBackground:(UIApplication *)application{
[myLocationManager startMonitoringSignificantLocationChanges];
}
当应用程序回到前台时,我会执行以下操作:
-(void)applicationDidBecomeActive:(UIApplication *)application{
//Other irrelevant code
[myLocationManager stopMonitoringSignificantLocationChanges];
[myLocationManager startUpdatingLocation];
}
这对我来说似乎合情合理。我的问题是,我应该在stopUpdatingLocation
事件中调用applicationDidEnterBackground
方法吗?像这样:
-(void)applicationDidEnterBackground:(UIApplication *)application{
[myLocationManager stopUpdatingLocation];
[myLocationManager startMonitoringSignificantLocationChanges];
}
我应该在哪里调用stopUpdatingLocation
方法?请告诉我是否有多个地方应该这样做。我假设任何错误事件应该停止更新?
答案 0 :(得分:2)
我没有看到你在做什么有什么问题。请注意,我有一个大量使用位置服务的商业应用程序,我正在重写它以提高它的性能并最大限度地减少电池使用。
我发布的版本主要使用sigLocationChanges(在后台和前台),但在不满意sigLocationChanges给我的位置质量时切换到使用startUpdatingLocation,因为我的UI必须大致准确地显示用户位置。我在每次事件发生后立即调用stopUpdatingLocation以最大限度地减少电池消耗。在我的发货版本中,这似乎工作正常,但我的日志文件找到了一小部分用户,他们似乎经常会遇到不好的位置,而且我的GPS硬件比我更喜欢。
同样在隐私设置中,为您的应用显示的位置图标类型将取决于您上次使用完整GPS定位模式的时间。我总是会显示位置图标,表明电池会受到严重影响,即使我每天只使用startUpdatingLocation几次,这可能会让我的用户对我的应用程序如何影响他们的电池寿命感到陌生。
在我的新版本中,为了最大程度地减少使用startUpdatingLocation的电池消耗,我已经将它的使用减少到希望为零。当应用程序激活时,我现在直接从位置管理器cLLocMgr.location获取当前位置。通常这是一个准确的位置,我的UI可以立即正确绘制(或刷新)。当某些视图被激活时我也会再次检查它以确保用户在保持我的应用程序打开的同时移动显示器保持运行状态。现在,如果手机在特定情况下的位置不好,我只会启动GPS硬件,在这种情况下,应用程序中绝对需要良好的位置。在这种情况下,我将它的使用限制在2分钟(我假设2分钟足够长,以便从GPS硬件获得最佳位置),并等待至少10分钟再让它再次使用。
您的问题没有给我足够的信息来说明您需要的准确程度以及您的位置显示的动态程度。但除非您需要超精确度和动态显示,否则您应该考虑仅使用当前位置而不旋转GPS硬件以节省电池电量。
编辑:这是我用于Jeraldo的实际代码,清理了一下。请注意,我触摸它已经有一年了,所以我对它有点生疏,希望我没有清理任何东西。
// Called at start to ask user to authorize location data access.
- (void) requestIOSLocationMonitoring {
#if TARGET_IPHONE_SIMULATOR
// If running in siumaltor turn on continuous updating (GPS mode)
// This is for testing as significant change isn't useful in simulator
// Set a movement threshold for new events. This is only used by continiuous mode, not sig change events
// Keep it as low as possible,but not so low as to generate spurious movements.
cLLocMgr.distanceFilter = 30;
// Use continuous location events in simulator.
// desired accuracy only works in continuious (high power) mode.
cLLocMgr.desiredAccuracy = kCLLocationAccuracyBest;
[cLLocMgr startUpdatingLocation];
#else
// If not in simulator app's default is significant change monitoring
[cLLocMgr startMonitoringSignificantLocationChanges];
#endif //TARGET_IPHONE_SIMULATOR
}
// Toggle back and forth between continius updates (GPS on) and
// significant change monitoring
- (void) setGPSMode: (bool) useGPSMode {
// Keep track of time since we last changed GPS mode
NSTimeInterval secsInThisMode = [[NSDate date] timeIntervalSinceDate: lastModeChange];
// inGPSMode is an object instance variable app uses to track mode it is in.
if (inGPSMode != useGPSMode) {
lastModeChange = [NSDate date];
if (!useGPSMode) {
// Tell app to operate as if continuous updating is off
inGPSMode = false;
#if TARGET_IPHONE_SIMULATOR
// But keep using continuous location events in simulator for testing.
cLLocMgr.distanceFilter = 30;
#else
// Turn off continious updates for app on actual devices
[cLLocMgr stopUpdatingLocation];
#endif
} else if (secsInThisMode > cMinGPSModeBreak) {
// Only turn on continuous updating again if it's been off long enough
// Prevents GPS mode from running continiously and killing battery life
inGPSMode = true;
cLLocMgr.desiredAccuracy = kCLLocationAccuracyBest;
cLLocMgr.distanceFilter = kCLDistanceFilterNone;
[cLLocMgr startUpdatingLocation];
}
}
}