ios - 何时调用 [clLocationManager stopUpdatingLocation]

标签 ios cllocationmanager

为了节省应用中的电量,我决定在应用处于事件状态时混合使用 startUpdatingLocation,并在应用处于后台时进入 startMonitoringSignificantLocationChanges 模式。基本上,当应用程序进入后台时,我会执行以下操作:

-(void)applicationDidEnterBackground:(UIApplication *)application{
    [myLocationManager startMonitoringSignificantLocationChanges];
}

当应用程序返回前台时,我会执行以下操作:

-(void)applicationDidBecomeActive:(UIApplication *)application{
    //Other irrelevant code
    [myLocationManager stopMonitoringSignificantLocationChanges];
    [myLocationManager startUpdatingLocation];
}

无论如何,这对我来说似乎是合乎逻辑的。我的问题是,我应该在 applicationDidEnterBackground 事件中调用 stopUpdatingLocation 方法吗?就像这样:

-(void)applicationDidEnterBackground:(UIApplication *)application{
    [myLocationManager stopUpdatingLocation];
    [myLocationManager startMonitoringSignificantLocationChanges];
}

我到底应该在哪里调用 stopUpdatingLocation 方法?请告诉我是否有多个地方需要执行此操作。我假设任何错误事件都应该停止更新?

最佳答案

我不认为你所做的事情有什么问题。请注意,我有一个大量使用位置服务的商业应用程序,我正在重写它以提高其性能并最大限度地减少电池使用量。

我发布的版本主要使用 sigLocationChanges(在后台和前台),但当对 sigLocationChanges 提供的位置质量不满意时,会切换到使用 startUpdatingLocation,因为我的 UI 必须大致准确地显示用户位置。我在每次事件发生后立即调用 stopUpdatingLocation 以最大程度地减少电池消耗。在我的发布版本中,这似乎工作正常,但我的日志文件发现一小部分用户似乎经常获得不良位置,而且我对 GPS 硬件的旋转超出了我的喜好。

此外,在“隐私设置”中,为您的应用显示的位置图标类型将取决于您上次使用完整 GPS 定位模式的时间。我的应用程序总是显示位置图标,表明对电池的影响很大,即使我每天只短暂使用 startUpdatingLocation 几次,这可能会让我的用户对我的应用程序如何影响他们的电池生命周期产生偏执。

在我的新版本中,为了最大限度地减少使用 startUpdatingLocation 的电池消耗,我已将其使用量减少到零。当应用程序激活时,我现在直接从位置管理器 cLLocMgr.location 获取当前位置。通常这是一个准确的位置,并且我的 UI 可以立即正确绘制(或刷新)。当某些 View 被激活时,我还会再次检查它,以确保用户在保持应用程序打开的同时移动时,显示会保持不变。现在,只有在应用程序绝对需要良好位置的特定情况下,如果手机位置不佳,我才会启动 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];
        }
    }
}

关于ios - 何时调用 [clLocationManager stopUpdatingLocation],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14568453/

相关文章:

ios - 在没有 iBeacon 的情况下实现地理围栏时,当应用程序未运行时未调用 didEnterRegion 和 didDetermineState

ios - 在 Swift 的属性声明期间引用 self

ios - dyld : Library not loaded: @rpath/App. 框架/应用程序

ios - 如何查找 OpenVPN 是否已安装

swift - DidUpdateLocations 不存储位置,userLock 始终为 nil

swift - 没有调用 did Update To 位置

ios - Swift UIGestureRecogniser 跟随手指

ios - CoreData IOS中如何正确获取ObjectId?

ios - 如何在 iOS 13 中使用 `requestAlwaysAuthorization` 请求 CLLocationManager 中的地理位置?

iphone - 如何检查 iOS 4.2 之前的特定应用程序是否启用了位置服务?