iOS iBeacon: 如何以编程方式获取所有的ProximityUUID?

10
我想以程序方式查看广告数据包的全部proximityUUID。有些文章说在iOS上不可能,但在Android上是可能的。但我不相信,因为我找到了一款名为“BLExplr”的神奇应用程序具备这个功能。我需要将该功能实现到我的应用程序中。是否有人知道如何做或有好的示例?任何帮助都将不胜感激。
(更新于2014/1/17)
我相信@davidgyoung的答案是正确的。 Estimote信标的proximityUUID是“B9407F30-F5F8-466E-AFF9-25556B57FE6D”,但在BLExplr应用程序中显示的我的Estimote信标的UUID是另一个ID。

我发现了另一个名为“Light Blue”的应用程序,它具有相同的特性。但我仍然找不到可能的解决方案。我需要使用蓝牙框架通过读取BLE原始数据来解决问题吗?(我不确定是否可行) - zono
3个回答

28

很遗憾,在iOS上你不能这样做。当你说BLExplr和LightBlue可以做到这一点时,你混淆了蓝牙服务UUID和iBeacon Proximity UUID。这是两个非常不同的东西。

蓝牙服务UUID对iOS可见,但与iBeacon的标识符无关,对于处理iBeacon毫无用处。服务UUID由iOS每次看到蓝牙设备时生成,并且仅在蓝牙设备在范围内的时间内保持不变。如果你把蓝牙设备拿走并稍后再带回来,它将有一个不同的服务UUID。

iBeacon的标识符(ProximityUUID、Major、Minor)嵌入在蓝牙广告的主体中。在iOS设备上的问题是,苹果的CoreBluetooth API不允许访问原始广告主体,因此没有第三方应用程序能够读取这些标识符。苹果只允许使用特殊的iBeacon CoreLocation API访问这些标识符,但这些API要求你事先知道Proximity UUID。

很抱歉,我知道这不是你想听到的答案!(我也很抱歉!)值得一提的是,你可以在Android、MacOS、Linux和Windows上实现这一点。

请查看此处的详细信息。


1
非常感谢!你是对的!我附上了BLExplr的屏幕截图。服务UUID与Estimote信标的Proximity UUID不同。 - zono
1
@davidgyoung,你能告诉我Radius Networks应用商店中的“Locate”应用是如何在没有我的输入下读取我的UUID、Minor和Major值的吗?我正在开发一个需要获取未知UUID并将其与数据库中的内容进行比较的应用。谢谢。 - Estevex
无法实现。该应用程序预配置了十几个流行的UUID。您必须在您的信标上拥有一个流行的UUID。 - davidgyoung
好的谢谢。我成功地弄清了如何继续。再次感谢你。 - Estevex
@Estevex 你找到解决方案了吗?我也想知道如何在iOS中检测信标设备而不知道UUID。 - Akhtar
@davidgyoung 如果配置了"kCBAdvDataManufacturerData",并且所有这些细节都可以包含在其中,那么我们可以从中获取UUID、major和minor数据吗? - subin272

8

davidgyoung 部分错误,不能获取iBeacon信息。实际上,在OS X上你可以获得接近UUID,但是在iOS上不行。

CBPeripheraladvertisingData中,应该有一个名为kCBAdvDataManufacturerData的键;它是代表iBeacon广告信息的NSData这个键只在OS X上可用。

检查第二个字节是否等于0x02,前两个字节是否等于0x004c(十进制下为76),第四个字节(十进制下)+ 4等于数据长度(应该为25)。

NSRanges(抱歉,这里使用了Mac语法)
接近UUID:NSMakeRange(4, 16)
Major:NSMakeRange(20,2)
Minor:NSMakeRange(22,2)

为确保正确,您可以将值记录为十六进制(使用格式字符串%x),并确保它们与NSDatadescription匹配。


1
你用了什么iBeacon?它似乎不能用于Estimote Beacon。advertisementData = { kCBAdvDataIsConnectable = 1; kCBAdvDataLocalName = estimote; kCBAdvDataServiceData = { "Device Information" = <0ec9686a 05d8b60e c9686a>; }; } - YarGnawh
YarGnawh,我正在遵循iBeacon配置文件的广告数据大纲。这是CoreBluetooth的外围管理器进行广告宣传的方式。可能还有其他使用信标进行广告宣传的方法。Estimote可能会查找kCBAdvDataServiceData并连接到信标,然后读取一个特征来获取主要和次要信息。 - Nate Symer
1
此外,对于提供正确答案并回答问题的回答进行负面评价(特别是当其他人只是忽略该问题时)是愚蠢的。 - Nate Symer
1
继续上文,@NathanielSymer 应该添加一个简单的消息,如“接近 UUID 可以在符合 iBeacon 蓝牙协议规范的设备上找到,在 advertisementData 中使用 kCBAdvDataManufacturerData 键”,并且您应该删除“davidyoung 完全错误...”因为他不是,他只是部分正确和部分错误。 - Mysteltainn
6
我相信这种技术可以在OSX上运行,但不能在iOS上运行。我的测试显示,在iBeacon广告中上述的关键字在iOS上不存在。请参见此处链接:http://developer.radiusnetworks.com/2013/10/21/corebluetooth-doesnt-let-you-see-ibeacons.html - davidgyoung
显示剩余2条评论

0
NSRange uuidRange = NSMakeRange(4, 16);
NSRange majorRange = NSMakeRange(20, 2);
NSRange minorRange = NSMakeRange(22, 2);
NSRange powerRange = NSMakeRange(24, 1);

Byte uuidBytes[16];
[data getBytes:&uuidBytes range:uuidRange];
NSUUID *uuid = [[NSUUID alloc] initWithUUIDBytes:uuidBytes];

int16_t majorBytes;
[data getBytes:&majorBytes range:majorRange];
int16_t majorBytesBig = (majorBytes >> 8) | (majorBytes << 8);

int16_t minorBytes;
[data getBytes:&minorBytes range:minorRange];
int16_t minorBytesBig = (minorBytes >> 8) | (minorBytes << 8);

int8_t powerByte;
[data getBytes:&powerByte range:powerRange];



return @{ @"uuid" : uuid,
          @"major" : @(majorBytesBig),
          @"minor" : @(minorBytesBig),
          @"power" : @(powerByte)
          };

但UUID是设备UUID,而不是接近度UUID。


这个 data 变量的数据类型是什么?我们能否直接在这里使用 kCBAdvDataServiceData 数组? - Kamal Upasena
是的,数据为[advertisingData objectForKey:kCBAdvDataServiceData]。 - Jeanette Müller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接