我正在研究广告制造商特定数据的BLE传感器。是否有任何示例代码演示如何在Android中接收广告数据包并解析其有效负载?
非常感谢你的帮助。
答案 0 :(得分:18)
这就是我想要的:
BLE扫描API BluetoothAdapter.startLeScan(ScanCallback)需要回扫功能才能获得扫描结果。该方法需要如下所示:
private BluetoothAdapter.LeScanCallback ScanCallback =
new BluetoothAdapter.LeScanCallback()onLeScan(final BluetoothDevice device,
int rssi,
final byte[] scanRecord)
{...}
scanRecord变量是一个包含广告数据包有效负载的字节数组。
根据BLE规范,有效载荷的结构非常简单,如下所示:
数据包的长度最多为47个字节,包括:
对于广告传播频道,访问地址始终为0x8E89BED6。
PDU又有自己的头(2个字节:有效载荷的大小及其类型 - 设备是否支持连接等)和实际有效载荷(最多37个字节)。
最后,有效载荷的前6个字节是设备的MAC地址,实际信息最多可以有31个字节。
实际信息的格式如下:
第一个字节是数据的长度,第二个字节是类型,后跟数据。
如果他们不关心内容,这是一种允许任何应用程序跳过整个数据记录的聪明方法。
以下是确定广告数据包内容的示例代码:
parseAdvertisementPacket(final byte[] scanRecord) {
byte[] advertisedData = Arrays.copyOf(scanRecord, scanRecord.length);
int offset = 0;
while (offset < (advertisedData.length - 2)) {
int len = advertisedData[offset++];
if (len == 0)
break;
int type = advertisedData[offset++];
switch (type) {
case 0x02: // Partial list of 16-bit UUIDs
case 0x03: // Complete list of 16-bit UUIDs
while (len > 1) {
int uuid16 = advertisedData[offset++] & 0xFF;
uuid16 |= (advertisedData[offset++] << 8);
len -= 2;
uuids.add(UUID.fromString(String.format(
"%08x-0000-1000-8000-00805f9b34fb", uuid16)));
}
break;
case 0x06:// Partial list of 128-bit UUIDs
case 0x07:// Complete list of 128-bit UUIDs
// Loop through the advertised 128-bit UUID's.
while (len >= 16) {
try {
// Wrap the advertised bits and order them.
ByteBuffer buffer = ByteBuffer.wrap(advertisedData,
offset++, 16).order(ByteOrder.LITTLE_ENDIAN);
long mostSignificantBit = buffer.getLong();
long leastSignificantBit = buffer.getLong();
uuids.add(new UUID(leastSignificantBit,
mostSignificantBit));
} catch (IndexOutOfBoundsException e) {
// Defensive programming.
Log.e("BlueToothDeviceFilter.parseUUID", e.toString());
continue;
} finally {
// Move the offset to read the next uuid.
offset += 15;
len -= 16;
}
}
break;
case 0xFF: // Manufacturer Specific Data
Log.d(TAG, "Manufacturer Specific Data size:" + len +" bytes" );
while (len > 1) {
if(i < 32) {
MfgData[i++] = advertisedData[offset++];
}
len -= 1;
}
Log.d(TAG, "Manufacturer Specific Data saved." + MfgData.toString());
break;
default:
offset += (len - 1);
break;
}
}
感谢
mass让我朝着正确的方向前进!
答案 1 :(得分:3)
nv-bluetooth解析广告包的有效负载并返回AD结构列表。 AD结构格式在&#34; 11 ADVERTISING AND SCAN RESPONSE DATA FORMAT&#34; &#34;蓝牙核心规范4.2&#34;。
以下代码段是onLeScan方法的实现示例。
public void onLeScan(
BluetoothDevice device, int rssi, byte[] scanRecord)
{
// Parse the payload of the advertising packet.
List<ADStructure> structures =
ADPayloadParser.getInstance().parse(scanRecord);
// For each AD structure contained in the advertising packet.
for (ADStructure structure : structures)
{
if (structure instanceof IBeacon)
{
// iBeacon packet was found.
handleIBeacon((IBeacon)structure);
}
......
}
}
您可以将自己的解析器注册为ADPayloadParser,以获取特定于制造商的格式。有关详细信息,请参阅以下链接。
博客:http://darutk-oboegaki.blogspot.jp/2015/03/ibeacon-as-kind-of-ad-structures.html
GitHub:https://github.com/TakahikoKawasaki/nv-bluetooth
JavaDoc:http://takahikokawasaki.github.io/nv-bluetooth/
Maven:http://search.maven.org/#search|ga|1|a%3A%22nv-bluetooth%22
答案 2 :(得分:0)
编辑21.02.2016
我在下面链接的图书馆似乎已被移动; 见https://github.com/AltBeacon/android-beacon-library
您可以使用Android iBeacon Library开始。
有一个参考应用程序,您可以将其用于基础知识和模拟数据。 〜https://github.com/RadiusNetworks/ibeacon-reference-android~
一旦启动并运行,您可能希望导入库并将其与您的真实设备一起使用,网站上还有一些示例代码: http://developer.radiusnetworks.com/ibeacon/android/samples.html