我想通过BluetoothLeAdvertiser中的android.bluetooth.le类通过android传输iBluetooth。但是似乎我无法设置某些制造商规范数据字段来匹配iBeacon的数据。
iBeacon结构:
This和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创建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创建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。 (这还需要一个CallBack来告诉您蓝牙传输是否正常,那里没有问题)
mBluetoothLeAdvertiser.startAdvertising(mAdvertiseSettings, mAdvertiseData, mAdvertiseCallback);
这些步骤的问题是:
目前尚不清楚AdvertiseData.Builder.addManufacturerData()将第二个Byte [] ManufacturerSpecificData参数放在哪里,这取决于制造商规范数据,尤其是因为AdvertiseData.Builder.addManufacturerData()的第一个参数也是制造商规范数据中的制造商类型字段
以下BluetoothLeAdvertiser构造函数参数似乎将字节写入制造商规范数据,从而覆盖了addManufacturerData中添加的字节
AdvertiseSettings.Builder.setTxPowerLevel和PeriodicAdvertisingParameters.Builder.setIncludeTxPower会覆盖在AdvertiseData.Builder.addManufacturerData()中设置的TX功率(RSSI),并且在与其他一些BluetoothLeAdvertiser函数(例如BluetoothLeAdvertiser.startAdvertisingSet)结合使用时也会相互覆盖。
尽管在我给出的示例中未显示,但AdvertiseData.Builder还具有函数addServiceUuid,该函数将覆盖AdvertiseData.Builder.addManufacturerData()中添加的UUID
最初,我遵循this教程,并且正在传输Alt-Beacon。也许BluetoothLeAdvertiser类假设我仍在传输Alt-Beacon,其结构与iBeacons不同。
Alt-Beacon结构:
其他资源:
ti docs on BLE
decompiled source for all these functions
Android Bluetooth Low Energy tutorial
更新的代码
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();
}
最佳答案
我认为您的代码相当不错。一些说明:
苹果的制造商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();
}
关于android - 如何用BluetoothLeScanner类广播iBeacon?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48438881/