您可以根据需要将任何字节放入 iBeacon 广告中,但 iOS 严格限制了您可以读取哪些字节。如果您需要使用 iOS 来读取这些数据,那么您只有四个字节的蓝牙广告数据可以更改,iOS 可以读取这些数据。如果您只关心使用其他操作系统(OSX Mavericks、Android、Linux)读取字节,那么这不是问题。
为了解释 iOS 的局限性,看一下典型 iBeacon 广告的 advdata 会有所帮助,如下所示:
4C 00 # Company identifier code (0x004C == Apple)
02 15 # iBeacon advertisement indicator
e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 # ProximityUUID
00 00 # Major
00 00 # Minor
c5 # The 2's complement of the MeasuredPower
iOS 不允许您使用其CoreBluetooth API 访问上面显示的 advdata 的原始字节。 (详见here。)如果使用CoreLocation的iBeacon测距功能,可以读取ProximityUUID(16字节)、Major(2字节)和Minor(2字节)输出的广告数据。您提到的代码示例中设置的MeasuredPower 在iOS 中是不 直接可读的。它只是用作用于估计距 RSSI 距离的算法的输入。 (有关详细信息,请参阅here。)更改广告中的MeasuredPower 会影响此距离估计,但您无法可靠地确定实际的MeasuredPower 值。所以你不能将它用作自定义变量。
如上所述,iBeacon 广告还包括一个 16 字节的ProximityUUID。但是 iOS CoreLocation API 不允许您看到任何 iBeacon 广告,除非您预先指定匹配的 ProximityUUID。所以它真的没有任何用作自定义变量的用途。
您可以将什么用作自定义变量?您可以用于自定义变量的两个值是Major 字段和Minor 字段。其中每一个都是两个字节,如果您告诉 iOS CoreLocation 对所有具有给定 ProximityUUID 的 iBeacon 进行范围划分,您将获得范围更新,告诉您每个 Major 和 Minor 值,您可以编码任何您想要的这些字段中的数据。要访问这些,只需读取如下值:
-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region {
for (CLBeacon *iBeacon in iBeacons) {
// write code here to do something with iBeacon.major and iBeacon.minor
// which each will have values from 0-65535
}
}
以上所有内容都是仅限 iOS 的限制。其他平台允许您查看 advdata 的完整字节,因此您可以使用任何您想要的字节作为自定义变量。但是,如果您仍希望它们被识别为 iBeacon,则应不理会后两个字节(iBeacon 广告指示器)。
对于自定义变量,最佳做法是使用查找表将标准 iBeacon 标识符(ProximityUUID、Major、Minor)绑定到数据字段。此查找表可以嵌入到您的应用中,也可以使用 Radius Networks 的ProximityKit 等网络服务自动执行此操作。
全面披露:我是 Radius Networks 的首席工程师。