Проблема gattcallback Android BLE при чтении и записи

Я застрял в одной странной проблеме на прошлой неделе, и скоро я разозлюсь, Stackoverflow - моя последняя надежда. Я просто написал код для связи с устройством BLE. Сначала я просто пишу значение характеристики.

public void writeEnableCredentials(String keysFn) {
    if ( sGattCharList != null) {
        Log.i("Callback WEC Method: ", "Start!!!/n" );
        String val = keysFn.substring(0, 2);
        String val2 = keysFn.substring(2, 4);
        int val_1 = Integer.parseInt(val);
        int val_2 = Integer.parseInt(val2);
        byte[] rk_byte_Value = new byte[1];
        final byte[] rk_byte_Value_2 = new byte[1];
        rk_byte_Value[0] = (byte)(val_1 & 0xFF);
        rk_byte_Value_2[0] = (byte)(val_2 & 0xFF);
        sGattCharList.get(1).setValue(rk_byte_Value);
        boolean ok = sBluetoothGatt.writeCharacteristic(sGattCharList.get(1));
        Log.i("Callback WEC Method: ", "1 Verified = " + ok);
        if(ok) {
            final Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    sGattCharList.get(2).setValue(rk_byte_Value_2);
                    boolean ok = sBluetoothGatt.writeCharacteristic(sGattCharList.get(2));
                    Log.i("Callback WEC Method: ", "2 Verified = " + ok);
                }
            }, 100);
        }
    } else {
           Toast.makeText(activity, "Wait for services", Toast.LENGTH_SHORT).show();
    }
    Log.i("Callback WEC Method: ", "Stop!!!/n" );
}

Методы BluetoothGattCallback приведены ниже:

private final BluetoothGattCallback sGattCallback = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        if (newState == BluetoothProfile.STATE_CONNECTED) {
            Log.i("CallbackGatt","Connecting with " + sDevice.getsMac());
            sBluetoothGatt.discoverServices();
        }
        else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
            sBluetoothGatt.close();
            Log.i("CallbackGatt", "Disconnected from GATT server.");
        }
    }

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        services_List = gatt.getServices();
        sGattCharList = services_List.get(3).getCharacteristics();
        Log.i("CallbackGatt","Characteristic List Found: " + sGattCharList);
    }

    @Override
    public void onCharacteristicWrite(BluetoothGatt gatt,
                                      BluetoothGattCharacteristic characteristic, int status) {
        if(status == BluetoothGatt.GATT_SUCCESS) {
            byte[] bytes = characteristic.getValue();
            System.out.println("ON Characteristic WRITE Callback: " + characteristic.getUuid()+"    value: "+bytes);
        }
    }

};

ПРОБЛЕМА: этот код отлично работает с API> 22. НО на API ‹= 22 BluetoothGattCallback не работает должным образом, иногда получен обратный вызов, но после повторного запуска той же сборки я не получаю обратные вызовы, и характеристика не записывается.

Журнал отладки Выполняется сборка 5.1.1

*Trying to write 1st time*
07-04 00:29:28.370 19270-19270/com.example.xxx.xxxx/Callback WEC Method:: Start!!!/n
07-04 00:29:28.371 19270-19270/com.example.xxx.xxxx I/Callback WEC Method:: 1 Verified = true
07-04 00:29:28.372 19270-19270/com.example.xxx.xxxx I/Callback WEC Method:: Stop!!!/n
07-04 00:29:28.472 9115-9185/? E/bt-btif: already has a pending command!!
07-04 00:29:28.472 9115-9185/? E/bt-att: GATTC_Write GATT_BUSY conn_id = 6
07-04 00:29:28.474 19270-19270/com.example.xxx.xxxx I/Callback WEC Method:: 2 Verified = true

*Trying to write 2nd time*
07-04 00:29:33.371 19270-19270/com.example.xxx.xxxx I/Callback WEC Method:: Start!!!/n 
07-04 00:29:33.371 9115-9185/? E/bt-att: GATTC_Write GATT_BUSY conn_id = 6
07-04 00:29:33.371 9115-9185/? E/GKI_LINUX: GKI_exception(): Task State Table
07-04 00:29:33.371 9115-9185/? E/GKI_LINUX: TASK ID [0] task name [BTU] state [1]
07-04 00:29:33.371 9115-9185/? E/GKI_LINUX: TASK ID [1] task name [BTIF] state [1]
07-04 00:29:33.371 9115-9185/? E/GKI_LINUX: TASK ID [2] task name [A2DP-MEDIA] state [1]
07-04 00:29:33.371 9115-9185/? E/GKI_LINUX: GKI_exception 65532 Freeing Linked Buf
07-04 00:29:33.372 9115-9185/? E/GKI_LINUX: ********************************************************************
07-04 00:29:33.372 9115-9185/? E/GKI_LINUX: * GKI_exception(): 65532 Freeing Linked Buf
07-04 00:29:33.372 9115-9185/? E/GKI_LINUX: ********************************************************************
07-04 00:29:33.372 19270-19270/com.example.xxx.xxxx I/Callback WEC Method:: 1 Verified = true
07-04 00:29:33.373 19270-19270/com.example.xxx.xxxx I/Callback WEC Method:: Stop!!!/n
07-04 00:29:33.474 9115-9185/? E/bt-att: GATTC_Write GATT_BUSY conn_id = 6
07-04 00:29:33.474 19270-19270/com.example.xxx.xxxx I/Callback WEC Method:: 2 Verified = true
07-04 00:29:33.474 9115-9185/? E/GKI_LINUX: GKI_exception(): Task State Table
07-04 00:29:33.474 9115-9185/? E/GKI_LINUX: TASK ID [0] task name [BTU] state [1]
07-04 00:29:33.474 9115-9185/? E/GKI_LINUX: TASK ID [1] task name [BTIF] state [1]
07-04 00:29:33.474 9115-9185/? E/GKI_LINUX: TASK ID [2] task name [A2DP-MEDIA] state [1]
07-04 00:29:33.474 9115-9185/? E/GKI_LINUX: GKI_exception 65532 Freeing Linked Buf
07-04 00:29:33.474 9115-9185/? E/GKI_LINUX: ********************************************************************
07-04 00:29:33.474 9115-9185/? E/GKI_LINUX: * GKI_exception(): 65532 Freeing Linked Buf
07-04 00:29:33.474 9115-9185/? E/GKI_LINUX: ********************************************************************
07-04 00:29:33.562 339-339/? I/Gobi: vendor/qcom/proprietary/RIDL/RIDLClient/RIDLSQL.cpp:1920: GetTransState() EBADF
07-04 00:29:33.562 339-339/? I/Gobi: vendor/qcom/proprietary/RIDL/RIDLClient/MainCore.cpp:1346: Failed to get TransState, rc
07-04 00:29:33.562 339-339/? I/Gobi: vendor/qcom/proprietary/RIDL/RIDLClient/RIDLSQL.cpp:1920: GetTransState() EBADF

убить приложение => очистить кеш => запустить приложение => установить соединение => попытаться написать => убить приложение

После этого процесса 4 раза я наконец получил обратный вызов: D

07-04 00:34:39.144 26148-26148/com.example.xxx.xxxx I/Callback WEC Method:: Start!!!/n
07-04 00:34:39.147 26148-26148/com.example.xxx.xxxx I/Callback WEC Method:: 1 Verified = true
07-04 00:34:39.147 26148-26148/com.example.xxx.xxxx I/Callback WEC Method:: Stop!!!/n
07-04 00:34:39.233 26148-26166/com.example.xxx.xxxx I/System.out: ON Characteristic WRITE Callback: 0000fff2-0000-1000-8000-00805f9b34fb
07-04 00:34:39.247 26148-26148/com.example.xxx.xxxx I/Callback WEC Method:: 2 Verified = true
07-04 00:34:39.331 26148-26165/com.example.xxx.xxxx I/System.out: ON Characteristic WRITE Callback: 0000fff3-0000-1000-8000-00805f9b34fb

Если вам нужны другие подробности, спрашивайте. Также скажите, пожалуйста, что такое: E / GKI_LINUX: GKI_exception, спасибо.


person Salman Naseem    schedule 03.07.2017    source источник


Ответы (1)


Вам нужно дождаться обратного вызова записи, прежде чем запускать новую операцию. Простое ожидание 100 мс никогда не гарантирует срабатывания, поскольку для получения обратного вызова может потребоваться больше времени.

person Emil    schedule 03.07.2017
comment
Но он отлично работает с API ›22. если ожидания 100 мс недостаточно, то почему я получаю обратный вызов в таком случае? - person Salman Naseem; 04.07.2017
comment
Что бы вы ни говорили, просто подождать несколько мс не гарантируется. Вам нужно дождаться обратного звонка. - person Emil; 06.07.2017