我有一个 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 个字节长的唯一 ID。 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);
}
};
Android 有没有办法像 iOS 一样将完整的本地名称包含在广播中?
谢谢!
如果您查看
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);
}