【问题标题】:Ranging Beacons only works when app running?测距信标仅在应用程序运行时有效?
【发布时间】:2013-10-09 02:58:01
【问题描述】:

当应用程序未运行时,我很难让它工作。我实现了locationManager:didRangeBeacons:inRegion:,当应用程序在前台或后台运行时调用它,但是当我退出应用程序并锁定屏幕时它似乎没有做任何事情。位置服务图标消失了,我从不知道我进入了信标范围。 LocalNotification 是否仍然有效?

我在后台模式 (XCode 5) 中选择了位置更新和使用蓝牙 LE 配件,我认为我不需要它们。

非常感谢任何帮助。

-(void)watchForEvents { // this is called from application:didFinishLaunchingWithOptions
    id class = NSClassFromString(@"CLBeaconRegion");
    if (!class) {
        return;
    }

    CLBeaconRegion * rflBeacon = [[CLBeaconRegion alloc] initWithProximityUUID:kBeaconUUID identifier:kBeaconString];
    rflBeacon.notifyOnEntry = YES;
    rflBeacon.notifyOnExit = NO;
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    [self.locationManager startRangingBeaconsInRegion:rflBeacon];
    [self.locationManager startMonitoringForRegion:rflBeacon];
}

-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region {
    if (beacons.count == 0 || eventRanged) { // breakpoint set here for testing
        return;
    }

    eventRanged = YES;
    if (backgroundMode) { // this is set in the EnterBackground/Foreground delegate calls
        UILocalNotification *notification = [[UILocalNotification alloc] init];
        notification.alertBody = [NSString stringWithFormat:@"Welcome to the %@ event.",region.identifier];
        notification.soundName = UILocalNotificationDefaultSoundName;
        [[UIApplication sharedApplication] presentLocalNotificationNow:notification];
    }

    // normal processing here...
}

【问题讨论】:

  • “(我之前确实有这个工作,它会在锁定屏幕上发出通知。现在这不起作用。)”......你改变了什么?
  • OK.. 我确实找到了如何在后台和上面的问题更新时让我的徽章再次出现在锁定屏幕上:[self.locationManager startMonitoringForRegion:rflBeacon];
  • 这可能对你有帮助:stackoverflow.com/questions/19127282/…
  • 我在研究这个问题时看到了这一点。根据那个答案,它应该自动发生。显然,这对我来说并不是那么自动:(
  • 应该在 iOS 7.1 上修复。是吗? beekn.net/2014/03/…

标签: ios ios7 ibeacon


【解决方案1】:

使用位置更新,用于在后台定位信标的 iOS 9 代码:

  1. 打开项目设置 -> 功能 -> 后台模式 -> 将 Location UpdatesUses Bluetooth LE accessories 切换为 ON

  2. 创建CLLocationManager,请求Always监控授权(别忘了在应用的NONSLocationAlwaysUsageDescription中添加Application does not run in backgroundNSLocationAlwaysUsageDescription)并设置以下属性:

    locationManager!.delegate = self
    locationManager!.pausesLocationUpdatesAutomatically = false
    locationManager!.allowsBackgroundLocationUpdates = true
    
  3. 开始对信标和监控区域进行测距:

    locationManager!.startMonitoringForRegion(yourBeaconRegion)
    locationManager!.startRangingBeaconsInRegion(yourBeaconRegion)
    locationManager!.startUpdatingLocation()
    
    // Optionally for notifications
    UIApplication.sharedApplication().registerUserNotificationSettings(
        UIUserNotificationSettings(forTypes: .Alert, categories: nil))
    
  4. 实现CLLocationManagerDelegate 并在您的didEnterRegion 中同时发送startRangingBeaconsInRegion()startUpdatingLocation() 消息(也可选择发送通知)并在didExitRegion 中设置stopRangingBeaconsInRegion()stopUpdatingLocation() /p>

请注意,此解决方案有效,但由于电池消耗和客户隐私,Apple 不推荐它!

更多:https://community.estimote.com/hc/en-us/articles/203914068-Is-it-possible-to-use-beacon-ranging-in-the-background-

【讨论】:

  • 我建议将“注意”部分加粗,这很严重;)感谢您的回答,尤其是链接!
【解决方案2】:

这是您在后台范围内需要遵循的过程:

  1. 对于任何CLBeaconRegion,始终保持在后台或前台进行监控并保持notifyEntryStateOnDisplay = YES
  2. notifyEntryStateOnDisplay 在后台调用 locationManager:didDetermineState:forRegion:,所以实现这个委托调用...

...像这样:

- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region{

   if (state == CLRegionStateInside) {


        //Start Ranging
        [manager startRangingBeaconsInRegion:region];
    }

   else{

        //Stop Ranging
        [manager stopRangingBeaconsInRegion:region];
    }

}

我希望这会有所帮助。

【讨论】:

  • 位置管理器的代理可以是任何对象还是应用程序代理应该这样做?对我来说,只有当 appdelegate 是 locationmanager 的代表时它才有效……你知道为什么吗?
  • 是的,它可以与任何对象一起使用 - 请参阅此示例 github.com/manishnath/iBeaconCenter
  • 次要评论:您需要使用 (CLBeaconRegion *) 对区域进行类型转换,因为 startRangingBeaconsInRegion 需要一个 CLBeaconRegion * 并且 didDetermineState 传递一个 CLRegion *
【解决方案3】:

监控可以启动未运行的应用。测距不能。

监控启动您的应用程序的关键是在您的CLBeaconRegion 上设置这个记录不充分的标志:region.notifyEntryStateOnDisplay = YES; 即使在完全重启手机后,这也可以在区域转换时启动您的应用。但有几点需要注意:

  1. 您的应用程序仅在几秒钟内启动到后台。 (尝试将 NSLog 语句添加到 applicationDidEnterBackground 和 AppDelegate 中的其他方法,看看发生了什么。)
  2. iOS 可以自行决定是否输入了CLBeaconRegion。我发现它最多需要四分钟。

就测距而言,即使您不能让测距唤醒您的应用,您也可以让您的应用同时进行监控和测距。如果监控唤醒您的应用程序并将其置于后台几秒钟,则测距回调会立即启动。这使您有机会在您的应用仍在运行时执行任何快速测距操作。

编辑:进一步调查证明notifyEntryStateOnDisplay 对后台监控没有影响,因此无论您是否有此标志,上述内容都应该有效。见this detailed explanation and discussion of delays you may experience

【讨论】:

  • 四分钟范围是受认可的 iBeacon 的特征,还是尝试模仿 iBeacon 的限制?四分钟距离我们希望用户看到的东西有几个街区。
  • 我的猜测,这只是一个猜测,iOS 试图通过仅每 4 分钟左右进行一次蓝牙扫描来节省电量,当没有应用程序处于前台测距或监控时。
  • 我不确定notifiyEntryStateOnDisplay 是否具有您认为的效果。我的理解是,当设置为YES 时,iOS 会延迟通知您的应用程序区域进入通知,直到用户唤醒设备的显示屏,而不是立即发送它们。 Apple 在 WWDC 演示文稿中给出的示例是一个会员卡应用程序,您不想在有人经过商店时对手机进行 ping 操作,但您希望在用户在店内主动开始使用手机时显示通知它。
  • 查看我上面的编辑回复。我做了更多的测试,让我相信这个标志对后台监控没有影响,除了你真正唤醒屏幕的时候。并且当设置该标志时,后台监控回调不会延迟您只需在屏幕唤醒时获得附加回调。请参阅上面编辑中的详细讨论和证明。
【解决方案4】:

您在此处执行两项独立的操作 - “测距”信标和监视一个区域。您可以在后台监控区域,但不能监控范围信标。

因此,locationManager:didRangeBeacons:inRegion: 的实现不会在后台被调用。相反,您对startMonitoringForRegion 的调用将导致调用以下一个/一些方法:

– locationManager:didEnterRegion:
– locationManager:didExitRegion:
– locationManager:didDetermineState:forRegion:

这些将在后台调用。您可以在此时触发本地通知,就像在您的原始代码中一样。

【讨论】:

    【解决方案5】:

    如果您只是想在进入信标区域时收到通知,您的应用当前应该唤醒。我知道的唯一背景限制实际上是在 iOS 设备上托管 iBeacon。在这种情况下,应用程序需要在前台物理打开。对于这种情况,您最好直接执行 CoreBluetooth CBPeripheralManager 实现。这样你就可以在后台拥有一些广告能力。

    【讨论】:

    • 我确实发现如果我 startMonitoringForRegion 使用该信标作为区域,那么如果应用程序在后台运行,我将在锁定屏幕上收到通知。我认为 startMonitoringForRegion 会在应用程序尚未运行时启动它。
    • 根据 Apple 的 AirLocate 示例代码:“didDetermineState():用户可以在应用程序未运行时进入或离开区域。发生这种情况时,CoreLocation 将立即启动应用程序,调用此委托方法我们会通过本地通知让用户知道。”
    • 是的,我没有正确阅读问题。我只是在后台指代 iBeacon 托管。即,如果您正在运行托管 iBeacon 的应用程序,则该应用程序需要在前台运行,其他人才能进入该区域。我会编辑。
    • 无论如何,如果 CLBeaconLocation 不在后台,则无法激活应用程序,如在 iOS 7.0.2 中。非常令人失望。
    • 是的,我对 iBeacon 的东西寄予厚望……但结果证明它只是 CoreBluetooth 的淡化版本,并没有改善 CB 的任何缺陷
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-02
    • 1970-01-01
    • 2015-05-14
    • 1970-01-01
    相关资源
    最近更新 更多