xcode 从后台获取位置时,Location.Horizo​​ntalAccuracy 太差了

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9797777/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 23:43:49  来源:igfitidea点击:

Location.HorizontalAccuracy too bad when getting location from background

iphoneobjective-ciosxcodecllocationmanager

提问by Rafael Moreira

I'm writing an app that monitors the user's location. I have a CLLocationManager object that uses startMonitoringSignificantLocationChanges, so I can get locations updates from the background when the app is not running. I have setup my application didFinishLaunchingWithOptions so if I get a location key I fire up my manager to get the user's location. Everything works fine but the problem is that every time I get a location from the background, the Horizontal Accuracy of this location is very bad. In most of the cases it is 1414 m.

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

Does anybody know why the horizontal accuracy is so bad when the location comes from the background? Is there anything I can do to get locations with better accuracy in the background?

有人知道为什么当位置来自背景时水平精度如此糟糕吗?我可以做些什么来在后台获得更准确的位置?

When the app is running all the locations I get are very accurate, this only happens when the location comes from the background. Does that have anything to do with the number of cell towers I have in my city? I was thinking maybe the device doesn't use gps of wifi nodes to get locations in the background.

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

Anyways, Any help here is appreciated. Please share your thoughts.

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

Thanks!

谢谢!

回答by Ash Furrow

The accuracy of locations returned by CLLocationManageris determined by the desiredAccuracy, which is by default, kCLLocationAccuracyBest, and by the available accuracy of the device. For instance, you may get less accurate locations if the device's battery is low, or you may get more accurate locations if they are still cached from another app.

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

However, getting you incredibly accurate coordinates drains a significant amount of power from the battery and will drain the device. Applications in the background are probably limited to a much lower resolution of accuracy to improve battery performance.

但是,为您提供极其准确的坐标会消耗大量电池电量并耗尽设备电量。后台应用程序可能仅限于以低得多的精度分辨率来提高电池性能。

Accurate locations require a lot of power to use the GPS radio while less accurate locations can rely on nearby wifi hotspots and the cell towers within range of the phone.

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

As your application resumes from the background, the system will try to improve the accuracy of the results you get. It's a tricky concept, but take a look at the Maps application on your phone. At first, the circle representing your location is very large; as the system gets a more accurate sense of your location, the circle becomes smaller. This visualization represents the phone using more power to get a more precise location.

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

You'll see a similar phenomenon with CLLocationManageras your app resumes from the background: you'll get an inaccurate location and receive subsequent, more accurate updates.

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

It's a compromise between convenience and battery life that Apple had to make when designing their APIs. The first update to a user's location probably won't be that accurate unless they were just using the Maps application and the location is cached.

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

The best advice I can give you is to listen for subsequent updates from the location manager and update your UI accordingly. Good luck!

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

回答by Hubert Kunnemeyer

As the name states: The startMonitoringSignificantLocationChanges notification is only there to let you know that a the the user's location significantly different from the last one checked. It's your job when you receive that Notification to update your location according to the desired accuracy you want.The notification won't do that for you. It is only going to let you know the location has change so you can deal with the situation accordingly. If you don't know how to get a better accuracy you may want to check out the Apple sample code for LocateMe.Here's a snippet that stores the accuracy(bestEffortAtLocation) then tests the accuracy each time the delegate is called until a better result comes in or a time-out occurs.:

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

- (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
} 

The credit goes to Apple because this is a snippet straight from their sample code LocateMe:

归功于 Apple,因为这是直接来自他们的示例代码 LocateMe 的片段:

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

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

So when you get the notification and need to get a better result you'll need to update the accuracy and see if that gives you a better result.

因此,当您收到通知并需要获得更好的结果时,您需要更新准确度,看看这是否会给您带来更好的结果。