Android BLE write 'onCharacteristicWrite' returns status GATT_WRITE_NOT_PERMITTED

南楼画角 提交于 2021-01-28 06:08:56

问题


I've been trying to create a small Android BLE app that sends some bytes of data to a BLE device (an HM-10 module).

Using existing applications on the Play Store I've been able to test the connection and this seems to be working but I seem to keep running into problems when trying to implement it in my own app.

This is the code I'm using to connect to the BLE device using its MAC-address:

// Initializes Bluetooth adapter.
    final BluetoothManager bluetoothManager =
            (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
    mBluetoothAdapter = bluetoothManager.getAdapter();

    BluetoothDevice myDevice = mBluetoothAdapter.getRemoteDevice("00:09:83:20:8D:18");

    mBluetoothGatt = myDevice.connectGatt(getApplicationContext(), true, mGattCallback);

and sending data using the writeCharacteristic method:

@Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status)
    {
        //Now we can start reading/writing characteristics
        String TAG = "";
        if (status == BluetoothGatt.GATT_SUCCESS)
        {
            for (BluetoothGattService gattService : gatt.getServices())
            {
                Log.i(TAG, "onServicesDiscovered: ---------------------");
                Log.i(TAG, "onServicesDiscovered: service=" + gattService.getUuid());
                for (BluetoothGattCharacteristic characteristic : gattService.getCharacteristics())
                {
                    Log.i(TAG, "onServicesDiscovered: characteristic=" + characteristic.getUuid());

                    if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0)
                    {
                        Log.w(TAG, "onServicesDiscovered: found LED");

                        //byte[] b = { '$', 0x05, 0x05, 0x10, '$', 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!', '\r', '\n' };
                        byte[] b = {0x01};

                        characteristic.setValue(b); // call this BEFORE(!) you 'write' any stuff to the server
                        boolean myResult = mBluetoothGatt.writeCharacteristic(characteristic);

                        Log.i(TAG, "onServicesDiscovered: , write bytes?! " + b);
                    }
                }
            }

            //broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
        } else {
            Log.w(TAG, "onServicesDiscovered received: " + status);
        }
    }

I use the following code to receive the callback:

@Override
    public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
        if(status != BluetoothGatt.GATT_SUCCESS){
            Log.d("onCharacteristicWrite", "Failed write, retrying: " + status);
            gatt.writeCharacteristic(characteristic);
        }
        Log.d("onCharacteristicWrite", ByteArrToHex(characteristic.getValue()));
        super.onCharacteristicWrite(gatt, characteristic, status);
    }

For some reason the status variable in the callback always contains status 3 (GATT_WRITE_NOT_PERMITTED). I've been trying to look for the specific meaning of this status but I wasn't able to find anything useful.

Does anyone have an idea what I'm missing here?

EDIT: I also noticed that calling getPermissions() on the characteristic in onCharacteristicWrite returns 0.

EDIT: Alright, so thanks to @Emil I was able to change the example to check for the service UUID which resulted into this:

if (gattService.getUuid().equals(UUID.fromString("0000ffe0-0000-1000-8000-00805f9b34fb")))
                {
                    for (BluetoothGattCharacteristic characteristic : gattService.getCharacteristics())
                    {
                        Log.i(TAG, "onServicesDiscovered: characteristic=" + characteristic.getUuid());

                        if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0)
                        {
                            Log.w(TAG, "onServicesDiscovered: found LED");

                            //byte[] b = { '$', 0x05, 0x05, 0x10, '$', 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!', '\r', '\n' };
                            byte[] b = "$\5\5\16Hello world!\r\n".getBytes();
                            //byte[] b = {0x01};

                            characteristic.setValue(b); // call this BEFORE(!) you 'write' any stuff to the server
                            boolean myResult = mBluetoothGatt.writeCharacteristic(characteristic);

                            Log.i(TAG, "onServicesDiscovered: , write bytes?! " + b);
                        }
                    }
                }

The BLE device now receives the data properly!


回答1:


It means that the remote device doesn't permit you to write to that characteristic (although it has set the writable bit in the properties...)

But you shouldn't loop through the services like that and just write to the first writable characteristic you find. Instead find the correct service and characteristic by uuid to make sure you find the correct one.



来源:https://stackoverflow.com/questions/48731701/android-ble-write-oncharacteristicwrite-returns-status-gatt-write-not-permitte

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!