如何在Android中像iOS一样广播BLE本地名称?

18

我有一个 Android 应用程序,用服务 UUID 和本地名称广告 BLE 广播数据。问题是这个“本地名称”(又称蓝牙设备名称)仅限于 8 个字符,每个字符都是 16 位 Unicode 表示,因此每个字符占用 2 个字节。每当我尝试将设备名称更改为 9 个字符长时,BLE 广播启动失败,出现错误 1,即

  public static final int ADVERTISE_FAILED_DATA_TOO_LARGE = 1;

我知道GAP档案的广播包长度为27字节,其中7字节用于标头,因此应该有20字节可以自由使用,而不仅仅是16字节?

这里有一个问题困扰着我:

iOS在广播ble广告头时,我在ScanRecord中获得了设备的完整本地名称,而不仅仅是16个字节的限制。只是广播的一部分,我在这里没有建立GATT连接。

iOS是如何做到这一点的呢?例如,在我的Android上,我能够从iOS广告广播中检索出一个14个字符,28字节长的唯一标识符。28个字节比蓝牙4.0标准规定的27个字节限制要长。为什么Android能够捕捉到超过27字节的完整广播呢?为什么我的“本地名称”或设备名称最多只能为8个字符或16个字节,否则就无法开始广播呢?

这是我的代码:

         final BluetoothLeAdvertiser advertiser = mBluetoothAdapter.getBluetoothLeAdvertiser();

        //advertise settings
        final AdvertiseSettings.Builder settingsBuilder = new AdvertiseSettings.Builder();
        settingsBuilder.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY);
        settingsBuilder.setConnectable(true);
        settingsBuilder.setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH);

        //advertise data
        AdvertiseData.Builder dataBuilder = new AdvertiseData.Builder();
        ParcelUuid uuid = new ParcelUuid(UUID.fromString("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"));
        dataBuilder.addServiceUuid(uuid);

        mBluetoothAdapter.setName("12345678"); //8 characters works, 9+ fails
        dataBuilder.setIncludeDeviceName(true);

     if (advertiser!=null) {
         advertiser.startAdvertising(settingsBuilder.build(), dataBuilder.build(), mAdvertiseCallback);
     } 

     mAdvertiseCallback = new AdvertiseCallback() {
         @Override
         public void onStartSuccess(AdvertiseSettings settingsInEffect) {
             super.onStartSuccess(settingsInEffect);
             Log.d(LOGN, "BLE STARTED ADVERTISING BROADCAST "+settingsInEffect);

         }

         @Override
         public void onStartFailure(int errorCode) {
                 super.onStartFailure(errorCode);
                 Log.d(LOGN, "BLE ADVERTISING FAILED TO START: "+errorCode);
         }
    };

安卓有没有像iOS一样在广播中包含完整的本地名称的方法?

谢谢!


有什么新情况吗?你最终找到什么了吗? - Rastikan
抱歉,目前还没有任何内容 :( 据我所知,iOS遵循标准,将其广播数据包按顺序分成20字节的一组。如果这是真的,那么Android可以将多个广播头重新组合在一起的事实意味着硬件堆栈也应该能够分割自己的广播头,如果它们超过20字节... - DritanX
你难道不是在调用这个函数:"dataBuilder.addServiceUuid",它会尝试将服务数据放入广告包中吗? - Lance Nanek
@LanceNanek 在哪里看到的?http://developer.android.com/intl/ru/reference/android/bluetooth/le/AdvertiseData.Builder.html#addServiceUuid(android.os.ParcelUuid) - DritanX
1个回答

1
如果您查看StartAdvertising的重载版本,您会发现有一个额外的参数用于扫描响应。您可以将本地名称放在扫描响应数据中。请记得从数据生成器中删除setIncludeDeviceName
AdvertiseData.Builder scanResponseBuilder = new AdvertiseData.Builder();
mBluetoothAdapter.setName("123456789")
scanResponseBuilder.setIncludeDeviceName(true);

//...

if (advertiser!=null) {
     advertiser.startAdvertising(settingsBuilder.build(), dataBuilder.build(), scanResponseBuilder.SetIncludeDeviceName.build(), mAdvertiseCallback);
 } 

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