我想通过BluetoothLeAdvertiser中的android.bluetooth.le类通过android传输iBluetooth。但是似乎我无法设置某些制造商规范数据字段来匹配iBeacon的数据。


iBeacon结构:


Thisthis告诉您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.setTxPowerLevelPeriodicAdvertisingParameters.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/

10-11 22:14
查看更多