Java Android AdvertiseData Builder-在执行回调时添加多个服务
我正在尝试为我的Android外围设备(化石手表)构建多个BLE服务,但发现在创建AdvertiseData时,不能一个接一个地添加多个服务,必须等待回调: 如果Android中的所有BLE外设都是这样(而不是特定于上面链接的实际用途),我如何利用AdvertiseData.Builder()和.addServiceUuid()在BluetoothGattServerCallback>onServiceAdded中添加我的第二个和第三个服务 换句话说,我如何等待回调执行并继续添加服务?如何重构代码以适应这种情况 我尝试重写回调,并检查回调中通过的服务是否是第一个,然后添加第二个,等等。我现在收到一个错误(如下所示),因此我不太确定是否在其已包含的方法(包括在下面的代码中)之外处理AdvertiseData.Builder()部分:Java Android AdvertiseData Builder-在执行回调时添加多个服务,java,android,callback,bluetooth-lowenergy,Java,Android,Callback,Bluetooth Lowenergy,我正在尝试为我的Android外围设备(化石手表)构建多个BLE服务,但发现在创建AdvertiseData时,不能一个接一个地添加多个服务,必须等待回调: 如果Android中的所有BLE外设都是这样(而不是特定于上面链接的实际用途),我如何利用AdvertiseData.Builder()和.addServiceUuid()在BluetoothGattServerCallback>onServiceAdded中添加我的第二个和第三个服务 换句话说,我如何等待回调执行并继续添加服务?如何重构
无法解析方法“addServiceUuid(android.os.parceluid)”
我浏览了谷歌等网站,没有发现任何类似的问题
回拨:
private BluetoothGattServerCallback mGattServerCallback = new BluetoothGattServerCallback() {
@Override
public void onServiceAdded(int status, BluetoothGattService service){
if (service == commandsService){ // if the service added is the first one, add the second
advData.addServiceUuid(new ParcelUuid(CONFIRMS_SERVICE_UUID));
} else if (service == confirmsService){ // if the service is the second, add the third
advData.addServiceUuid(new ParcelUuid(ALERTS_SERVICE_UUID));
} else {
// All three should be added, success!
}
}
广告已开始,如果包含以下注释,则会显示一个错误(如下所示):
private void startAdvertising() {
BluetoothAdapter bluetoothAdapter = mBluetoothManager.getAdapter();
mBluetoothLeAdvertiser = bluetoothAdapter.getBluetoothLeAdvertiser();
if (mBluetoothLeAdvertiser == null) {
Log.w(TAG, "Failed to create advertiser");
return;
}
AdvertiseSettings settings = new AdvertiseSettings.Builder()
.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_BALANCED)
.setConnectable(true)
.setTimeout(1000)
.setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM)
.build();
advData = new AdvertiseData.Builder()
.setIncludeDeviceName(false)
.setIncludeTxPowerLevel(false)
.addServiceUuid(new ParcelUuid(COMMANDS_SERVICE_UUID))
// .addServiceUuid(new ParcelUuid(CONFIRMS_SERVICE_UUID))
// .addServiceUuid(new ParcelUuid(ALERTS_SERVICE_UUID))
.build();
mBluetoothLeAdvertiser
.startAdvertising(settings, advData, mAdvertiseCallback);
}
如果这两行未注释,则会发生以下错误:
W/GattServer: LE Advertise Failed: 1
W/Binder: Caught a RuntimeException from the binder stub implementation.
java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
at java.util.ArrayList.get(ArrayList.java:437)
at android.bluetooth.BluetoothGattServer$1.onServiceAdded(BluetoothGattServer.java:129)
at android.bluetooth.IBluetoothGattServerCallback$Stub.onTransact(IBluetoothGattServerCallback.java:85)
at android.os.Binder.execTransact(Binder.java:697)
我希望了解如何利用AdvertiseData.Builder并添加多个服务,使用回调一次添加一个。我不明白如何将回调和构建器一起使用,以及等待回调添加下一个服务的正确方法是什么
资源-我用这个项目作为开始的例子:在我偶然发现这个问题之前,我一直面临着同样的问题。
T Linkin的评论让我想到了这个问题 事实证明,您不能同时添加所有的
BluetoothGattService
s。通过按顺序添加它们,可以防止该问题 您可以将所有服务保留在
队列中
:
fun advertise() {
val gattServices: List<BluetoothGattService> = createServices()
this.addServiceQueue = LinkedList(gattServices)
if(addServiceQueue.isEmpty()) {
startAdvertisement()
} else {
val firstItem = addServiceQueue.poll()
gattServer?.addService(firstItem)
}
}
看一看这张照片。看起来你的广告包太大了。添加两个完整的128位服务UUID对于广告来说太多了。您必须使用更小的UUID并制作自己的定制广告包看起来像是另一个用户@alextk做的,但没有说明如何:
override fun onServiceAdded(status: Int, service: BluetoothGattService?) {
Log.d(TAG, "onServiceAdded: status $status")
if (status == BluetoothGatt.GATT_SUCCESS) {
Log.d(TAG, "onServiceAdded: success")
val nextItem = addServiceQueue.poll()
if(nextItem == null) {
startAdvertisement()
} else {
gattServer?.addService(nextItem)
}
}
}