如何使用BluetoothLeScanner类广播iBeacon?

3
我希望通过BluetoothLeAdvertiser类,使用android.bluetooth.le包下的功能,在Android上传输iBluetooth。但是我发现无法设置一些制造商特定数据(Manufacturer spec data)字段,使其与iBeacon相匹配。


iBeacon结构: iBeacon数据包

这里这里介绍了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

我是一名有用的助手,可以为您翻译文本。




我一直在遵循这个教程,其中包括以下步骤:

  1. Create the AdvertiseData object using AdvertiseData.Builder.addManufacturerData() (which I believe should be the Manufacturer spec data, see below for the issues with that)

    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();
    }
    
  2. Create 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();
    }
    
  3. Broadcast the AdvertiseSettings and AdvertiseData using BluetoothLeAdvertiser. (This also takes a callBack that tells if Bluetooth transmission worked, no problems there)

    mBluetoothLeAdvertiser.startAdvertising(mAdvertiseSettings, mAdvertiseData, mAdvertiseCallback);
    
这些步骤存在的问题是: 起初我遵循了这篇教程,发送了一个Alt-Beacon信号。也许BluetoothLeAdvertiser类认为我仍在发送Alt-Beacon信号,而该信号的结构与iBeacons不同。 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();

}

parsed data nrfBeacon raw packet data

1个回答

2
我认为你的代码非常好。一些备注:
  • 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();
}

我是指索引为1的字节。-> mManufacturerData.put(1, (byte)0xAC); -> 替换为 mManufacturerData.put(1, (byte)0x15); - undefined
刚刚尝试了这些值,这个信标在 nrfConnect(一个蓝牙接收应用程序)中仍然显示为 AltBeacon。 - undefined
1
你能更新你的问题并且能够展示nrf应用程序中广告帧的原始视图吗?如果更改制造商ID,它将不再是Altbeacon。 - undefined
@user4757074 我刚刚检查了你的实现和截图。从我的角度来看,这是一个有效的iBeacon帧,绝对不是AltBeacon格式。你可以使用Beaconscanner进行验证:http://play.google.com/store/apps/details?id=com.bridou_n.beaconscanner - undefined
Beaconscanner检测到一个带有我的UUID的iBeacon,而且代码没有任何更改!!! - undefined
显示剩余2条评论

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