簡體   English   中英

Android BLE AdvertiseData Builder - 在回調執行時添加多個服務

[英]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)
        }
    }
}

查看ble 廣告錯誤代碼 看起來您的廣告數據包太大。 添加兩個完整的 128 位服務 uuid 對於廣告來說太多了。 您必須使用較小的 uuid 並制作自己的自定義廣告數據包

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM