如何用BluetoothLeScanner广播iBeacon class?
How to broadcast iBeacon with the BluetoothLeScanner class?
我想使用 BluetoothLeAdvertiser class from android.bluetooth.le 通过 android 传输 iBluetooth。但似乎我无法设置某些 制造商规格数据 字段以匹配 iBeacon 的字段。
iBeacon结构:
This and this 告诉您 iBeacon 的 制造商规格数据 值需要包含什么。基本上:
Apple Company Identifier (Little Endian), 0x004c = 76
data type, 0x02 => iBeacon
data length, 0x15 = 21
uuid: 585CDE931B0142CC9A1325009BEDC65E
major: [0000]
minor: 0000
meaured power at 1 meter: 0xc5 = -59
我一直在关注具有以下步骤的 this tutorial:
创建 AdvertiseData object using AdvertiseData.Builder.addManufacturerData()(我认为应该是 制造商规格数据,请参阅下面的问题)
protected void setAdvertiseData() {
AdvertiseData.Builder mBuilder = new AdvertiseData.Builder();
ByteBuffer mManufacturerData = ByteBuffer.allocate(24);
byte[] uuid = getIdAsByte(UUID.fromString("0CF052C2-97CA-407C-84F8-B62AAC4E9020"));
mManufacturerData.put(0, (byte)0xBE); // Beacon Identifier
mManufacturerData.put(1, (byte)0xAC); // Beacon Identifier
for (int i=2; i<=17; i++) {
mManufacturerData.put(i, uuid[i-2]); // adding the UUID
}
mManufacturerData.put(18, (byte)0x00); // first byte of Major
mManufacturerData.put(19, (byte)0x09); // second byte of Major
mManufacturerData.put(20, (byte)0x00); // first minor
mManufacturerData.put(21, (byte)0x06); // second minor
mManufacturerData.put(22, (byte)0xB5); // txPower
mBuilder.addManufacturerData(224, mManufacturerData.array()); // using google's company ID
mAdvertiseData = mBuilder.build();
}
创建AdvertiseSettings using the AdvertiseSettings.Builder
protected void setAdvertiseSettings() {
AdvertiseSettings.Builder mBuilder = new AdvertiseSettings.Builder();
mBuilder.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_POWER);
mBuilder.setConnectable(false);
mBuilder.setTimeout(0);
mBuilder.setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM);
mAdvertiseSettings = mBuilder.build();
}
使用 BluetoothLeAdvertiser 广播 AdvertiseSettings 和 AdvertiseData。 (这也需要一个回调,告诉蓝牙传输是否有效,没有问题)
mBluetoothLeAdvertiser.startAdvertising(mAdvertiseSettings, mAdvertiseData, mAdvertiseCallback);
这些步骤的问题是:
不清楚 AdvertiseData.Builder.addManufacturerData() is putting its second Byte[] manufacturerSpecificData parameter in terms of the Manufacturer spec data, especially because the first parameter of AdvertiseData.Builder.addManufacturerData() 也是 制造商规格数据 中的 制造商类型 字段
以下 BluetoothLeAdvertiser 构造函数参数似乎将字节写入 制造商规范数据 ,覆盖在 addManufacturerData
中添加的字节
- AdvertiseSettings.Builder.setTxPowerLevel 和 PeriodicAdvertisingParameters.Builder.setIncludeTxPower 将覆盖 [=94= 中设置的 TX 功率 (RSSI) ]AdvertiseData.Builder.addManufacturerData() 并在与 BluetoothLeAdvertiser.startAdvertisingSet.[= 等其他一些 BluetoothLeAdvertiser 函数组合时会相互覆盖116=]
- 虽然我给的例子里没有显示,AdvertiseData.Builder also has the function addServiceUuid which would overwrite the UUID added in AdvertiseData.Builder.addManufacturerData()
起初我是按照 this 教程,发送一个 Alt-Beacon。也许 BluetoothLeAdvertiser class 假设我仍在传输与 iBeacon 结构不同的 Alt-Beacon。
Alt-Beacon 结构:
其他资源:
更新代码
public AdvertiseData getiBeaconData() {
AdvertiseData.Builder mBuilder = new AdvertiseData.Builder();
ByteBuffer mManufacturerData = ByteBuffer.allocate(24);
byte[] uuid = getIdAsByte(UUID.fromString(thisCont.getString( R.string.ble_uuid )) );
ParcelUuid parced = new ParcelUuid(UUID.fromString(thisCont.getString( R.string.ble_uuid )) );
/*
R.string.ble_uuid == CDB7950D-73F1-4D4D-8E47-C090502DBD63
这是关于 iBeacon 结构
http://smlie-blog.blogspot.com/2014/06/bluetooth-ibeacon-packet-format.html
*/
//mManufacturerData.put((byte)0x00); //Manufactor Id 1
//mManufacturerData.put((byte)0x4C); //Manufactor Id 2
// mManufacturerData.put((byte)0xBE); //ibeconid1
mManufacturerData.put((byte)0x02); //ibeconid2
mManufacturerData.put((byte)0x15); //Data length
for (byte i:uuid) {
mManufacturerData.put(i); // adding the UUID
}
mManufacturerData.put((byte)0x00); //major first
mManufacturerData.put((byte)0x00); //major second
mManufacturerData.put((byte)0x00); //minor first
mManufacturerData.put((byte)0x00); //minor second
//mManufacturerData.put((byte)0xC5); //TX power
/*
mManufacturerData.put((byte)0x1A); // Beacon Identifier was BE iBeacon = 00
mManufacturerData.put((byte)0xFF); // Beacon Identifier was AC iBeacon = 02
/* the above 2 lines are the ibeacon AD Indicator
for (byte i:uuid) {
mManufacturerData.put(i); // adding the UUID
}
mManufacturerData.put((byte)0x00); // first byte of Major
mManufacturerData.put((byte)0x00); // second byte of Major
mManufacturerData.put((byte)0x00); // first minor
mManufacturerData.put((byte)0x00); // second minor
mManufacturerData.put((byte)0xC5); // txPower (RSSI) (from tx)
mBuilder.addManufacturerData(16, mManufacturerData.array()); // using google's company ID
*/
mBuilder.addManufacturerData(76, mManufacturerData.array()); // using google's company ID
//mBuilder.addServiceUuid(parced);
return mBuilder.build();
}
我觉得你的代码很好。一些评论:
- Apple 的制造商 ID 是 76:
mBuilder.addManufacturerData(76, mManufacturerData.array())
- iBeacon 类型为 0x02:
mManufacturerData.put(0, (byte)0x02); // Beacon Identifier
- 长度为 0x15:
mManufacturerData.put(1, (byte)0x15); // Beacon Identifier
- 我不确定这是否有效:
UUID.fromString("0CF052C297CA407C84F8B62AAC4E9020")
。通常 fromString()
方法需要这样的东西:UUID.fromString("F0018B9B-7509-4C31-A905-1A27D39C003D")
总结一下:
protected void setAdvertiseData() {
AdvertiseData.Builder mBuilder = new AdvertiseData.Builder()
ByteBuffer mManufacturerData = ByteBuffer.allocate(23);
byte[] uuid = getIdAsByte(UUID.fromString("0CF052C297CA407C84F8B62AAC4E9020"));
mManufacturerData.put(0, (byte)0x02);
mManufacturerData.put(1, (byte)0x15);
for (int i=2; i<=17; i++) {
mManufacturerData.put(i, uuid[i-2]); // adding the UUID
}
mManufacturerData.put(18, (byte)0x00); // first byte of Major
mManufacturerData.put(19, (byte)0x09); // second byte of Major
mManufacturerData.put(20, (byte)0x00); // first minor
mManufacturerData.put(21, (byte)0x06); // second minor
mManufacturerData.put(22, (byte)0xB5); // txPower
mBuilder.addManufacturerData(76, mManufacturerData.array());
mAdvertiseData = mBuilder.build();
}
我想使用 BluetoothLeAdvertiser class from android.bluetooth.le 通过 android 传输 iBluetooth。但似乎我无法设置某些 制造商规格数据 字段以匹配 iBeacon 的字段。
iBeacon结构:
This and this 告诉您 iBeacon 的 制造商规格数据 值需要包含什么。基本上:
Apple Company Identifier (Little Endian), 0x004c = 76
data type, 0x02 => iBeacon
data length, 0x15 = 21
uuid: 585CDE931B0142CC9A1325009BEDC65E
major: [0000]
minor: 0000
meaured power at 1 meter: 0xc5 = -59
我一直在关注具有以下步骤的 this tutorial:
创建 AdvertiseData object using AdvertiseData.Builder.addManufacturerData()(我认为应该是 制造商规格数据,请参阅下面的问题)
protected void setAdvertiseData() { AdvertiseData.Builder mBuilder = new AdvertiseData.Builder(); ByteBuffer mManufacturerData = ByteBuffer.allocate(24); byte[] uuid = getIdAsByte(UUID.fromString("0CF052C2-97CA-407C-84F8-B62AAC4E9020")); mManufacturerData.put(0, (byte)0xBE); // Beacon Identifier mManufacturerData.put(1, (byte)0xAC); // Beacon Identifier for (int i=2; i<=17; i++) { mManufacturerData.put(i, uuid[i-2]); // adding the UUID } mManufacturerData.put(18, (byte)0x00); // first byte of Major mManufacturerData.put(19, (byte)0x09); // second byte of Major mManufacturerData.put(20, (byte)0x00); // first minor mManufacturerData.put(21, (byte)0x06); // second minor mManufacturerData.put(22, (byte)0xB5); // txPower mBuilder.addManufacturerData(224, mManufacturerData.array()); // using google's company ID mAdvertiseData = mBuilder.build(); }
创建AdvertiseSettings using the AdvertiseSettings.Builder
protected void setAdvertiseSettings() { AdvertiseSettings.Builder mBuilder = new AdvertiseSettings.Builder(); mBuilder.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_POWER); mBuilder.setConnectable(false); mBuilder.setTimeout(0); mBuilder.setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM); mAdvertiseSettings = mBuilder.build(); }
使用 BluetoothLeAdvertiser 广播 AdvertiseSettings 和 AdvertiseData。 (这也需要一个回调,告诉蓝牙传输是否有效,没有问题)
mBluetoothLeAdvertiser.startAdvertising(mAdvertiseSettings, mAdvertiseData, mAdvertiseCallback);
这些步骤的问题是:
不清楚 AdvertiseData.Builder.addManufacturerData() is putting its second Byte[] manufacturerSpecificData parameter in terms of the Manufacturer spec data, especially because the first parameter of AdvertiseData.Builder.addManufacturerData() 也是 制造商规格数据 中的 制造商类型 字段
以下 BluetoothLeAdvertiser 构造函数参数似乎将字节写入 制造商规范数据 ,覆盖在 addManufacturerData
中添加的字节- AdvertiseSettings.Builder.setTxPowerLevel 和 PeriodicAdvertisingParameters.Builder.setIncludeTxPower 将覆盖 [=94= 中设置的 TX 功率 (RSSI) ]AdvertiseData.Builder.addManufacturerData() 并在与 BluetoothLeAdvertiser.startAdvertisingSet.[= 等其他一些 BluetoothLeAdvertiser 函数组合时会相互覆盖116=]
- 虽然我给的例子里没有显示,AdvertiseData.Builder also has the function addServiceUuid which would overwrite the UUID added in AdvertiseData.Builder.addManufacturerData()
起初我是按照 this 教程,发送一个 Alt-Beacon。也许 BluetoothLeAdvertiser class 假设我仍在传输与 iBeacon 结构不同的 Alt-Beacon。
Alt-Beacon 结构:
其他资源:
更新代码
public AdvertiseData getiBeaconData() {
AdvertiseData.Builder mBuilder = new AdvertiseData.Builder();
ByteBuffer mManufacturerData = ByteBuffer.allocate(24);
byte[] uuid = getIdAsByte(UUID.fromString(thisCont.getString( R.string.ble_uuid )) );
ParcelUuid parced = new ParcelUuid(UUID.fromString(thisCont.getString( R.string.ble_uuid )) );
/*
R.string.ble_uuid == CDB7950D-73F1-4D4D-8E47-C090502DBD63 这是关于 iBeacon 结构 http://smlie-blog.blogspot.com/2014/06/bluetooth-ibeacon-packet-format.html */
//mManufacturerData.put((byte)0x00); //Manufactor Id 1
//mManufacturerData.put((byte)0x4C); //Manufactor Id 2
// mManufacturerData.put((byte)0xBE); //ibeconid1
mManufacturerData.put((byte)0x02); //ibeconid2
mManufacturerData.put((byte)0x15); //Data length
for (byte i:uuid) {
mManufacturerData.put(i); // adding the UUID
}
mManufacturerData.put((byte)0x00); //major first
mManufacturerData.put((byte)0x00); //major second
mManufacturerData.put((byte)0x00); //minor first
mManufacturerData.put((byte)0x00); //minor second
//mManufacturerData.put((byte)0xC5); //TX power
/*
mManufacturerData.put((byte)0x1A); // Beacon Identifier was BE iBeacon = 00
mManufacturerData.put((byte)0xFF); // Beacon Identifier was AC iBeacon = 02
/* the above 2 lines are the ibeacon AD Indicator
for (byte i:uuid) {
mManufacturerData.put(i); // adding the UUID
}
mManufacturerData.put((byte)0x00); // first byte of Major
mManufacturerData.put((byte)0x00); // second byte of Major
mManufacturerData.put((byte)0x00); // first minor
mManufacturerData.put((byte)0x00); // second minor
mManufacturerData.put((byte)0xC5); // txPower (RSSI) (from tx)
mBuilder.addManufacturerData(16, mManufacturerData.array()); // using google's company ID
*/
mBuilder.addManufacturerData(76, mManufacturerData.array()); // using google's company ID
//mBuilder.addServiceUuid(parced);
return mBuilder.build();
}
我觉得你的代码很好。一些评论:
- Apple 的制造商 ID 是 76:
mBuilder.addManufacturerData(76, mManufacturerData.array())
- iBeacon 类型为 0x02:
mManufacturerData.put(0, (byte)0x02); // Beacon Identifier
- 长度为 0x15:
mManufacturerData.put(1, (byte)0x15); // Beacon Identifier
- 我不确定这是否有效:
UUID.fromString("0CF052C297CA407C84F8B62AAC4E9020")
。通常fromString()
方法需要这样的东西:UUID.fromString("F0018B9B-7509-4C31-A905-1A27D39C003D")
总结一下:
protected void setAdvertiseData() {
AdvertiseData.Builder mBuilder = new AdvertiseData.Builder()
ByteBuffer mManufacturerData = ByteBuffer.allocate(23);
byte[] uuid = getIdAsByte(UUID.fromString("0CF052C297CA407C84F8B62AAC4E9020"));
mManufacturerData.put(0, (byte)0x02);
mManufacturerData.put(1, (byte)0x15);
for (int i=2; i<=17; i++) {
mManufacturerData.put(i, uuid[i-2]); // adding the UUID
}
mManufacturerData.put(18, (byte)0x00); // first byte of Major
mManufacturerData.put(19, (byte)0x09); // second byte of Major
mManufacturerData.put(20, (byte)0x00); // first minor
mManufacturerData.put(21, (byte)0x06); // second minor
mManufacturerData.put(22, (byte)0xB5); // txPower
mBuilder.addManufacturerData(76, mManufacturerData.array());
mAdvertiseData = mBuilder.build();
}