2

这是我的挑战。我有一个配置为 iBeacon 的万向节系列 20,我的目标是让我的用户在应用后台运行的情况下让他们的手机与信标保持近乎物理的接触。想想苹果支付。

我将发射功率一直设置为 -23,但它仍然太强,并且信标正在触发 DidEnterRegion 代表肉食,直到一英尺远。使用测距,我可以通过直接测量 rssi 来进一步阈值。该解决方案在应用程序运行时运行良好。我的问题是该解决方案在后台运行不可靠,因为它仅在 enterRegion 事件后几秒钟的范围内运行,然后停止。

有没有办法进一步抑制信标的信号强度或其他方式导致 locationManger:DidEnterRegion: 触发较低的 rssi 读数?

4

3 回答 3

3

在后台启用信标测距后(见下文),您Immediate将在委托函数的实现中检查具有接近性的信标locationManager(_:didRangeBeacons:inRegion)

func locationManager(manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], inRegion region: CLBeaconRegion) {
    let immediateBeacons = beacons.filter() { $0.proximity == .Immediate }
    if !immediateBeacons.isEmpty {
        let tappedBeacon = immediateBeacons.first!
        // Your code for processing tappedBeacon ...
    }
}

Immediate如果手机距离小于 30 厘米(默认传输功率),信标就会接近。如果进一步降低发射功率,可以降到5-10cm。tappedBeacon上面代码中的信标是您用手机轻敲或几乎要用手机触摸的信标。

那是容易的部分。在后台保持信标范围内的活动有点棘手。

首先,您必须在项目设置的“功能”部分的“后台模式”下启用“位置更新”。这会在项目的Info.plist文件中产生以下条目:

<key>UIBackgroundModes</key>
<array>
    <string>location</string>
    <string>audio</string>
</array>

其次,您需要以CLLocationManager正确的方式初始化一个对象:

func initLocating() {
    if CLLocationManager.isRangingAvailable() {
        self.locationManager.requestWhenInUseAuthorization()
        self.locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers
        self.locationManager.allowsBackgroundLocationUpdates = true
        self.locationManager.delegate = self
    }
}

这个函数通常是从init()你的类的函数中调用的CLLocationManagerDelegate。如果您的设备完全支持测距,则此功能会请求位置更新授权。然后,它将 设置desiredAccuracykCLLocationAccuracyThreeKilometers,这将关闭除蜂窝塔三角测量之外的任何定位方法。这不是后台更新所必需的,但它可以使手机的电池寿命更长。

对于后台测距,必须允许后台更新allowsBackgroundLocationUpdates = true. 函数的最后一行简单地将这个类设为 ,只要可见信标或其属性发生变化,CLLocationManagerDelegate就会触发该函数。locationManager(_:didRangeBeacons:inRegion)

第三,您必须在需要时开始位置更新。这可能是应用程序的整个生命周期,也可能是由某个条件触发的。

func startLocating() {
    self.locationManager.startUpdatingLocation()
    self.locationManager.startRangingBeaconsInRegion(CLBeaconRegion(proximityUUID: self.proximityID, identifier: "AllBeacons"))
}

第一次调用通常会开始位置更新。如果没有这个调用,后台的信标测距最终将停止。第二个调用专门为您感兴趣的信标区域启动信标范围。它触发locationManager(_:didRangeBeacons:inRegion).

如果您可以停止测距信标一段时间,您可以使用以下功能。它只是 的倒数startLocating()

func stopLocating() {
    self.locationManager.stopRangingBeaconsInRegion(CLBeaconRegion(proximityUUID: self.proximityID, identifier: "AllBeacons"))
    self.locationManager.stopUpdatingLocation()
}

仅在需要时停止和启动信标测距是延长手机电池寿命的一种措施。

我在最近的一篇文章中详细描述了背景中的信标测距。以上是我帖子的精简版。

于 2016-01-09T00:44:56.773 回答
1

几个提示:

  1. 与其降低信标上的发射功率,不如将其调至最大,以获得可接受的电池寿命。这样做的原因是因为您将使用您的 RSSI 读取技术获得更一致的 RSSI 读数。

  2. 您可以使用我在此处的博客文章中的技术将背景范围延长至 3 分钟 然后,在进入区域后,您可以通过测距 10 秒左右收集 RSSI 样本,如果平均值足够强,则触发您的逻辑。

请小心使用多种设备(iPhone 4S/5/6、iPod、iPad 变体)进行测试,因为每种设备的蓝牙天线增益略有不同,您需要调整阈值以使其适用于您的应用程序所在的所有设备是兼容的。

于 2016-01-08T21:50:17.093 回答
1

这可能不是您问题的答案,但将其作为建议。Apple 仅在应用程序处于前台时向用户推荐 Ranging。在您的应用处于后台时使用监控

Apple:使用测距确定信标的接近度 为了在您的应用中促进一致的结果,请仅在您的应用处于前台时使用信标测距。如果您的应用程序位于前台,则设备可能在用户手中,并且设备对目标信标的视野中的障碍物较少。通过仅在用户积极使用设备时处理传入的信标信号,在前台运行还可以延长电池寿命。

几个月以来,我一直在使用 iBeacon。Estimote是领先的信标制造商。你可能想参考 Estimote 的博客是否可以在后台使用信标测距?

只是想帮忙。对不起,如果我没有回答你的问题。

于 2016-01-09T06:12:38.707 回答