【问题标题】:Location.HorizontalAccuracy too bad when getting location from background从后台获取位置时,Location.Horizo​​ntalAccuracy 太糟糕了
【发布时间】:2012-04-05 13:37:51
【问题描述】:

我正在编写一个监控用户位置的应用程序。我有一个使用 startMonitoringSignificantLocationChanges 的 CLLocationManager 对象,因此我可以在应用程序未运行时从后台获取位置更新。我已经设置了我的应用程序 didFinishLaunchingWithOptions 所以如果我得到一个位置密钥,我会启动我的经理来获取用户的位置。一切正常,但问题是每次我从背景中获取位置时,该位置的水平精度都非常差。在大多数情况下,它是 1414 米。

有谁知道为什么当位置来自背景时水平精度会这么差? 我可以做些什么来在后台获得更准确的位置吗?

当应用程序运行时,我获得的所有位置都非常准确,只有当位置来自后台时才会发生这种情况。这与我所在城市的手机信号塔数量有关吗?我在想也许设备不使用 wifi 节点的 gps 在后台获取位置。

无论如何,这里的任何帮助表示赞赏。 请分享您的想法。

谢谢!

【问题讨论】:

  • 其他人的研究longweekendmobile.com/2010/07/22/… 提到“CLLocationManager 倾向于在很短的时间内报告多个事件,即使在后台(相隔不到 10 秒)......第二个事件会比第一个更准确”
  • 布莱恩感谢您的链接。那里有一些非常有用的信息。他们在那里提到,从后台获取的位置精确到 500m,但这取决于您所在的城市。我一直在巴西利亚 - 巴西测试我的应用程序,到目前为止我得到的最佳精度是 1200m。

标签: iphone objective-c ios xcode cllocationmanager


【解决方案1】:

CLLocationManager 返回的位置精度由desiredAccuracy(默认为kCLLocationAccuracyBest)和设备的可用精度决定。例如,如果设备的电池电量不足,您可能会获得不太准确的位置,或者如果仍然从另一个应用程序缓存它们,您可能会获得更准确的位置。

但是,获取极其精确的坐标会消耗大量电池电量并耗尽设备。背景中的应用程序可能仅限于低得多的精度分辨率以提高电池性能。

准确的位置需要大量电力才能使用 GPS 无线电,而不太准确的位置可能依赖于附近的 wifi 热点和手机范围内的手机信号塔。

当您的应用程序从后台恢复时,系统将尝试提高您获得的结果的准确性。这是一个棘手的概念,但请看一下手机上的地图应用程序。一开始,代表你所在位置的圆圈很大;随着系统更准确地了解您的位置,圆圈会变小。此可视化表示手机使用更多电量来获取更精确的位置。

当您的应用从后台恢复时,您会看到与 CLLocationManager 类似的现象:您将获得一个不准确的位置并随后收到更准确的更新。

这是 Apple 在设计 API 时必须在便利性和电池寿命之间做出的妥协。用户位置的第一次更新可能不会那么准确,除非他们只是使用地图应用程序并且位置已被缓存。

我能给您的最佳建议是听取位置管理器的后续更新并相应地更新您的 UI。祝你好运!

【讨论】:

    【解决方案2】:

    顾名思义:startMonitoringSignificantLocationChanges 通知只是为了让您知道用户的位置与上次检查的位置明显不同。当您收到通知时,您的工作就是根据您想要的准确度更新您的位置。通知不会为您执行此操作。它只会让您知道位置发生了变化,以便您可以相应地处理情况。如果您不知道如何获得更高的准确度,您可能需要查看 Apple 的 LocateMe 示例代码。这是一个存储准确度(bestEffortAtLocation)的 sn-p,然后在每次调用委托时测试准确度,直到更好结果进来或发生超时。:

    - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
        // store all of the measurements, just so we can see what kind of data we might receive
        [locationMeasurements addObject:newLocation];
        // test the age of the location measurement to determine if the measurement is cached
        // in most cases you will not want to rely on cached measurements
        NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
        if (locationAge > 5.0) return;
        // test that the horizontal accuracy does not indicate an invalid measurement
        if (newLocation.horizontalAccuracy < 0) return;
        // test the measurement to see if it is more accurate than the previous measurement
        if (bestEffortAtLocation == nil || bestEffortAtLocation.horizontalAccuracy > newLocation.horizontalAccuracy) {
            // store the location as the "best effort"
            self.bestEffortAtLocation = newLocation;
            // test the measurement to see if it meets the desired accuracy
            //
            // IMPORTANT!!! kCLLocationAccuracyBest should not be used for comparison with location coordinate or altitidue 
            // accuracy because it is a negative value. Instead, compare against some predetermined "real" measure of 
            // acceptable accuracy, or depend on the timeout to stop updating. This sample depends on the timeout.
            //
            if (newLocation.horizontalAccuracy <= locationManager.desiredAccuracy) {
                // we have a measurement that meets our requirements, so we can stop updating the location
                // 
                // IMPORTANT!!! Minimize power usage by stopping the location manager as soon as possible.
                //
                [self stopUpdatingLocation:NSLocalizedString(@"Acquired Location", @"Acquired Location")];
                // we can also cancel our previous performSelector:withObject:afterDelay: - it's no longer necessary
                [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(stopUpdatingLocation:) object:nil];
            }
        }
        // update the display with the new location data
    } 
    

    这要归功于 Apple,因为这是直接来自他们的示例代码 LocateMe 的 sn-p:

    http://developer.apple.com/library/ios/#samplecode/LocateMe/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007801-Intro-DontLinkElementID_2

    因此,当您收到通知并需要获得更好的结果时,您需要更新准确性并查看是否可以为您带来更好的结果。

    【讨论】:

    • 休伯特,感谢您的回复。这实际上是我在我的应用程序中使用的确切代码,它在应用程序运行时运行良好。但是在后台我会在每次调用代表时不断测试准确性,但准确性总是很差。我认为Ash在这里说的很对。当应用程序在后台时,手机不会使用 GPS 来检索位置以节省电池,并且仅从手机信号塔获得的位置的准确性很差,至少在我的城市是这样。也许在一个有更多可用手机信号塔的城市,这种准确性可能会好一些。
    • 很高兴您发现我的建议很有帮助 - 您应该考虑将其标记为已接受的答案。
    猜你喜欢
    • 1970-01-01
    • 2017-10-16
    • 1970-01-01
    • 2022-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-17
    • 1970-01-01
    相关资源
    最近更新 更多