Android BLE gattcallback 读写问题

Android BLE gattcallback issue on read and write

上周我陷入了一个奇怪的问题,它很快就会让我发疯,Whosebug 是我最后的希望。 我只是简单地写了一段代码来与 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 上运行良好。 BUT 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,谢谢。

您需要等待写入回调才能发出新操作。简单地等待 100 毫秒永远不能保证工作,因为它可能需要更长的时间才能获得回调。