【问题标题】:Accuracy of "Region Monitoring" on iOS 6iOS 6 上“区域监控”的准确性
【发布时间】:2012-12-21 04:59:29
【问题描述】:

我正在尝试制作一个基于位置的应用程序,该应用程序需要在打开后不断更新位置。我一直在寻找一种在应用关闭时将位置保留在后台的方法,但我发现这不是最好的方法,因为它会很快耗尽任何 iPhone 的电池电量。

长话短说,我发现了“区域监控”,因为我知道它们与 Apple 用于其应用“提醒”的相同,也适用于位置。然后我使用该选项来测试我的应用程序,我意识到在模拟器中“从不”进入方法“didEnterRegion”,尽管它是正确创建的:

-(void) locationManager: (CLLocationManager *) manager didEnterRegion: (CLRegion *) region
 {
     NSLog (@ "entering the region");
     CLLocation * location1 = manager.location;
     CLLocation * location2 = [[CLLocation alloc] initWithLatitude: latitud.doubleValue longitude: longitud.doubleValue];
 }

我终于意识到该方法被调用了,但只有当我离开大部分区域并回到该区域时,这表明它不起作用,因为我已经在那个位置(所有这些都在模拟器中),奇怪的是它不是,模拟器的位置距离监控区域有几英里!这导致我认为这是准确性的问题,尽管创建半径为 50 或 100 米的区域正在扩展 3 或 4 公里,所以我没用。

有没有人知道iOS 6模拟器是否有这个错误或精度问题?我还没有开发者许可,可以直接在我的 iPhone 上测试它,我还不想购买它,因为我的应用程序还远未完成,感谢您对此主题的任何帮助。

提前致谢。

【问题讨论】:

    标签: ios location ios-simulator region cllocation


    【解决方案1】:

    我建议进行实际的地面测试。区域监控精度因测试位置而异。

    第二个选项是使用区域监控来唤醒应用程序并启动标准位置服务。为此,您需要获得在后台运行应用程序的权限。苹果可能不会批准这一点。我们的应用使用这种方法被拒绝了。

    【讨论】:

      【解决方案2】:

      DidEnterRegion 和 ExitRegion 不是很准确。大约 +, - 150m 精度。

      但是 -(void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations 非常准确。使用它来找出您所在地区的坐标/当前位置

      CLLocation *currentLocation = [locations lastObject];
      
       if ([self.ARegionYouSetBeforeHand containsCoordinate:currentLocation.coordinate])
      {
       //you arrived at this region!!
      }
      

      【讨论】:

        【解决方案3】:

        区域监控(通常)在与“重大位置变化”位置服务相同的基础上工作。也就是说,它使用手机信号塔位置; Apple 建议您通常可以预期 1 公里左右的精度,但警告说实际精度会随着您所在地区的手机信号塔的密度而变化。您可以在核心位置的WWDC videos 中找到有关此主题的更多背景信息。

        这可能是可行的——我没有尝试过——使用区域监控来(唤醒您的应用并)大致猜测用户的位置,然后在CLLocationManager 中使用更高精度的模式来获得更精确的修复。

        【讨论】:

        • 我尝试过同样的事情,是的......它有效,但对我来说有点“不雅”。即使我在创建区域时尝试强制调用方法“didEnterRegion”并比较用户位置和区域点之间的距离,如果这个距离超过 1 公里,那么我直接调用“didEnterRegion”方法,但是这对我来说看起来不太好。对于我的应用程序来说,1 公里太多了!我需要最大 200 米的精度。
        • 在我自己的测试中,我发现区域监控非常不准确。我也经历了几公里之外的准确性。 Apple 确实说过您需要穿越一个区域并在该区域内停留大约 20 秒才能被视为跨区域。
        • 是的,@Zhang,在我的调查中,我发现您需要跨越一个区域才能进入“didEnterRegion”方法,但即便如此,Apple 确实在文档中说“区域监控”是通过“洗衣店”之类的地方创建警报。我希望准确度足以用于真正的实用程序
        • Apple 的提醒应用在我试用时运行良好。正如预期的那样,每次我在我家时都会触发它。虽然,我不确定他们是否使用区域监控。在我自己的测试中,它也每次都会触发,但经常会错过。你不会得到激光准确的数据。我自己的测试表明,我大部分时间都在 500 米左右,我的半径在 150 到 200 米之间。
        • 既然你这个rickster似乎很有名气,我可以问你这个吗?即使在我的 iPhone 中,几米的半径也有数百米的半径。因此,当用户输入 100m 半径而不是预期的 5m 时,目的地就到达了。这是我发布的澄清问题:stackoverflow.com/questions/22417818/…
        【解决方案4】:

        在完成时,我意识到区域监控的准确性对于大多数用途来说已经足够了,但在模拟器中可能会很棘手,因为它没有 GPS 或手机硬件,无论如何,当我在我的设备中使用“区域监控”时,即使在功能正常工作的模拟路线。

        为了更准确,我将 CLLocationManager 的方法“startUpdatingLocation”调用到方法“didEnterRegion”中,这对我来说没问题。

        【讨论】:

        • 即使是真正的 iPhone,半径几米的区域最终也会变成半径数百米的区域。
        【解决方案5】:

        我在 iPhone 5C 上使用蜂窝塔移动数据进行区域监控时遇到了同样的问题,禁用了 WiFi,当我距离我保留区域的监控点 1.95 公里时,我习惯于很快调用 didEnterRegion半径 100.0 米。太早了。

        Apple 有一些阈值,由当前可用的硬件和定位技术决定。所以对我来说,它可能是 1800 米左右的早期价值。

        我建议保持最小半径(例如 25.0 代表 500.0 区域)或者如果通知如此珍贵,请使用 didUpdateLocations 委托方法并确定您的区域并通知相同。

        问候, 考希克

        【讨论】:

          【解决方案6】:

          我发现内置的区域监控不够准确,无法满足我的需求。如果你需要更高的准确率,首先适当设置你的准确率,然后你可以使用这样的东西:

          (使用与@coolcool1994 相同的方法,但更深入一点并使用Swift 2.1。记得设置CLLocationManager 及其委托(下面的函数将驻留),并开始接收位置更新)

          var activeRegions = Set<String>()
          var monitoredRegions = [
            CLCircularRegion(center: CLLocationCoordinate2D(latitude: 0.0, longitude: 0.0),
              radius: 300, identifier: "Region1"),
            CLCircularRegion(center: CLLocationCoordinate2D(latitude: 0.0, longitude: 0.0),
              radius: 300, identifier: "Region2")
          ]
          
          func manuallyUpdateActiveRegionsFromLocation(location: CLLocation){
            // Optionally explicitly reject unwanted location updates
            // Setting the location manager delegate's desiredAccuracy should be enough
            let maxOldTime = 300 //5 minutes
            let minAccuracy = 300 //300 metres
            if abs(location.timestamp.timeIntervalSinceNow) > maxOldTime
              || location.horizontalAccuracy > minAccuracy {
                return
            }
          
            for monitoredRegion in monitoredRegions {
              if monitoredRegion.containsCoordinate(location.coordinate) {
                activeRegions.insert(monitoredRegion.identifier)
              } else {
                activeRegions.remove(monitoredRegion.identifier)
              }
            }
          
          }
          
          func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
            if let location = locations.last {
              manuallyUpdateActiveRegionsFromLocation(location)
            }
          }
          

          【讨论】:

            【解决方案7】:

            MK MapView 上的预定义 GPS 精度

            1. kCLLocationAccuracyBestForNavigation – 使用尽可能高的值
              通过额外的传感器数据提高准确度。

            2. kCLLocationAccuracyBest – 推荐的最高级别
              使用电池供电的设备的准确性。

            3. kCLLocationAccuracyNearestTenMeters - 精确到 10 米以内。

            4. CLLocationAccuracyHundredMeters – 精确到 100 米以内。

            5. kCLLocationAccuracyKilometer – 精确到一公里以内。

            6. kCLLocationAccuracyThreeKilometers – 精确到三公里
              公里。

            用法:

            var locationManager: CLLocationManager = CLLocationManager()
            
                //MapView Location
                locationManager.delegate = self
                locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
                locationManager.requestWhenInUseAuthorization()
                locationManager.startUpdatingLocation()
                locationManager.startUpdatingHeading()
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-07-17
              • 1970-01-01
              • 2013-11-20
              • 2018-05-21
              • 1970-01-01
              • 2014-05-23
              • 1970-01-01
              • 2015-12-09
              相关资源
              最近更新 更多