【问题标题】:iBeacon monitoring and ranging in backgroundiBeacon 在后台监控和测距
【发布时间】:2015-07-11 02:57:10
【问题描述】:

我花了几个月的时间开发基于 iBeacons 的应用程序,我真的很沮丧。

一般的想法是,当检测到信标时,会通知用户特定于该 iBeacon 的信息。

应用程序设计如下,所有 iBeacons 具有相同的 UUID,Major 确定建筑物(博物馆、商店……),Minor 确定特定产品(图片、鞋子……)。所以这个应用程序可能服务于多个客户端。

当应用程序启动时,我开始使用我们的 UUID 对区域进行监视和测距。当应用程序处于前台时,一切正常。但是在后台或挂起状态下,问题就开始了。在后台或挂起状态下不允许测距。

我知道当您进入或退出信标区域时,该应用程序将在后台启动大约 5 秒钟。您可以在这 5 秒内在后台进行测距,之后 iOS 将再次暂停您的应用。

我设法利用这里学到的技术在后台将测距延长了 3 分钟。我还通过 notifyEntryStateOnDisplay = YES; 得到一个额外的回调;

但这还不够,如果客户端进入一个应用程序处于后台或挂起状态的区域,他会收到通知。并且在额外的 3 分钟内,如果测距检测到另一个 iBeacon,他会收到通知,但是当 3 分钟后台任务到期时,如果没有触发区域退出,他将不会再收到任何通知。

在这样的场景中没有真正的解决方案吗?我认为这是一种非常常见的情况,我很惊讶没有办法处理它。

已编辑:我试图按照 David Young 在回复中的建议通过监控两个区域来找到问题的解决方案。为了获得更多的进入/退出区域的事件。

我添加了我实现的代码来尝试监控两个区域。

但是我做错了一些事情,并且 didRangeBeacons:InRegion: 回调每 10 毫秒触发一次,而预期是每秒一次。

AppDelegate.m 上,我在didFinishLaunchingWithOptions: 内部执行以下操作

[self.locationManager startMonitoringForRegion:self.beaconRegion];
        [self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];
        [self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
        [self.locationManager startMonitoringForRegion:self.beaconRegion2];
        [self.locationManager stopRangingBeaconsInRegion:self.beaconRegion2];
        [self.locationManager startRangingBeaconsInRegion:self.beaconRegion2];

然后,在didRangeBeacons:InRegion:

- (void) locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region{

     if(beacons.count > 0){
          [self.locationManager stopRangingBeaconsInRegion:region];
          for (CLBeacon *beacon in beacons){
             NSLog(@"beacon detected major: %@ minor: %@", beacon.major,beacon.minor);
          }
           [self.locationManager startRangingBeaconsInRegion:region];   
     }

}

当我在模拟器上运行应用程序时,范围内的每个网络都有一个信标,该消息大约每 10 毫秒显示在控制台上。

我怀疑停止和重新开始测距打破了预期的回调流程,但是当只有一个区域在范围内时,回调按预期每秒发生。

【问题讨论】:

    标签: ios core-location ibeacon


    【解决方案1】:

    您描述的问题很常见。除了延长后台测距时间(您已经这样做了)之外,iOS 上没有灵丹妙药

    另外两种技术可能会有所帮助。这两种技术都涉及在您从一个信标传递到下一个信标时获得一个新的进入事件

    1. 获取允许您调低发射机功率的硬件信标(我公司的 RadBeacon 产品允许这样做),因此传输不会重叠。这样,当您从信标移动到信标时,您会收到一个退出事件,然后是一个新的进入事件。

    2. 重新设计您的标识符方案,以便 主要字段专用于识别多达 20 个不同的区域(基于 UUID 和主要 1-20)。然后,您监视所有这些区域。您的个人信标仍然可以根据需要使用未成年人,特别是作为触发消息传递的关键。放置信标时,请确保没有重叠传输的信标共享相同的专业。这将确保在您从一个移动到另一个时有一个新的后台进入事件。

    【讨论】:

    • 你能给我更多关于第一个选项的信息吗?第二个比较复杂,因为 Major 会识别客户端,这会改变整个后端和 android 应用程序。
    • 一个疯狂的想法,如果我要定义一个具有相同 UUID 但具有特定主要和次要的虚拟网络。然后我开始监视和测距 2 个区域,一个只有 UUID,第二个有 UUID 和特定的主要和次要。如果我分发虚构的网络信标,将它们放置在可能重叠的战略位置。我会得到额外的区域进入和退出?
    • 对于第一个选项,您只需让信标传输的距离更短,比如 10 米。只要您的信标相距至少 20 米,您就会在它们之间移动时收到退出/进入事件。您在上面评论中的第二个建议是我回答中第二个选项的可行变体。您只需要部署额外的信标来实现该变体。
    • 我正在尝试监控两个区域,但我发现了一些奇怪的东西。当我只监视一个区域时,“didRangeBeacons”回调每秒都会触发。但是现在,有 2 个区域,当它们都在范围内时,大约每 10 毫秒发射一次。这是预期的行为?
    • didRangeBeacons:InRegion: 应该在每个范围区域以 1Hz 的频率被调用。即使有 10 个远程区域,您也只会每 100 毫秒收到一次呼叫。你确定你没有在回调方法的循环中看到这个时间吗?如果是这样,那么同时测距 100 个可见信标可能会为您提供较少数量的回调,但每个信标的处理速度为每 10 毫秒一个。
    【解决方案2】:

    如果您跳过所有环节,后台的信标范围在 iOS 8 上工作得很好。

    首先,您需要正确的授权。将密钥 NSLocationAlwaysUsageDescription 添加到您的 Info.plist 中,然后调用

    [self.locationManager requestAlwaysAuthorization];
    

    您的应用必须具有Background ModeLocation Updates。在 Info.plist 中或通过 Capabilities 指定(与构建设置并行)。

    然后使用

    applicationDidBecomeActive 中检查授权
    switch([CLLocationManager authorizationStatus])
    {
        ...
    

    获得授权后,您需要这样做:

    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    // If you don't do this, location updates will pause after 15 minutes in the same place
    // Usually this is what you want, so I've left this line commented out
    // self.locationManager.pausesLocationUpdatesAutomatically = NO;
    
    // Create a NSUUID with the same UUID as the broadcasting beacon
    NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:kProximityUUID];
    
    _beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid
                                                      identifier:@"uk.co.airsource.testregion"];
    
    // Necessary to get continued background ranging.
    // See https://community.estimote.com/hc/en-us/articles/203914068-Is-it-possible-to-use-beacon-ranging-in-the-background-
    _locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
    [_locationManager startUpdatingLocation];
    [_locationManager startMonitoringForRegion:self.beaconRegion];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-22
      • 2014-07-16
      • 2016-08-24
      • 2013-12-25
      相关资源
      最近更新 更多