[英]Android BLE AdvertiseData Builder - adding multiple services when callback executes
我正在嘗試為我的 Android 外設(Fossil Watch)構建多個 BLE 服務,但發現在創建 AdvertiseData 時您無法一個接一個地添加多個服務,您必須等待回調: https://android.googlesource。 com/platform/packages/services/Car/+/master/TrustAgent/src/com/android/car/trust/SimpleBleServer.java#139
如果這適用於 Android 中的所有 BLE 外設(並且不特定於上面的鏈接實際用於的任何內容),我如何利用 AdvertiseData.Builder() 和 .addServiceUuid() 在 BluetoothGattServerCallback 中添加我的第二個和第三個服務 > onServiceAdded?
換句話說,我如何等待回調執行並繼續添加服務? 如何重構我的代碼以適應這種情況?
我嘗試覆蓋回調,並檢查回調中通過的服務是否是第一個,然后添加第二個,等等。我現在收到一個錯誤(如下),所以我不太確定要處理AdvertiseData.Builder() 在它已經存在的方法之外的部分(包含在下面的代碼中):
Cannot resolve method 'addServiceUuid(android.os.ParcelUuid)'
我瀏覽了谷歌和 SO 並沒有發現任何類似的問題。
打回來:
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!
}
}
廣告開始了,如果包含以下注釋掉的 .addServiceUuid() ,它會給我一個錯誤(如下):
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 並添加多個服務,使用回調一次添加一個。 我不明白如何將回調和構建器一起使用,以及等待回調添加下一個服務的正確方法是什么。
資源 - 我以這個項目為例開始: http : //nilhcem.com/android-things/bluetooth-low-energy
在我偶然發現這個問題之前,我面臨着同樣的問題。
T Linkin 的評論使我找到了正確的解決方案。
事實證明,您無法同時添加所有BluetoothGattService
。
通過按順序添加它們,您可以防止出現此問題。
您可以將所有服務保留在Queue
:
fun advertise() {
val gattServices: List<BluetoothGattService> = createServices()
this.addServiceQueue = LinkedList(gattServices)
if(addServiceQueue.isEmpty()) {
startAdvertisement()
} else {
val firstItem = addServiceQueue.poll()
gattServer?.addService(firstItem)
}
}
然后,在您的BluetoothGattServerCallback
實現onServiceAdded
方法:
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)
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.