Android BLE写'onCharacteristicWrite'返回状态GATT_WRITE_NOT_PERMITTED

时间:2018-02-11 12:56:09

标签: android bluetooth bluetooth-lowenergy

我一直在尝试创建一个小型Android BLE应用程序,它将一些字节的数据发送到BLE设备(HM-10模块)。

使用Play商店中的现有应用程序我已经能够测试连接,这似乎正在运行,但我似乎在尝试在我自己的应用程序中实现它时遇到问题。

这是我用于使用其MAC地址连接到BLE设备的代码:

// 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);

使用writeCharacteristic方法发送数据:

@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);
        }
    }

我使用以下代码接收回调:

@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);
    }

由于某种原因,回调中的状态变量始终包含状态3(GATT_WRITE_NOT_PERMITTED)。 我一直在努力寻找这种状态的具体含义,但我找不到任何有用的东西。

有没有人知道我在这里缺少什么?

编辑:我还注意到onCharacteristicWrite上的特性调用getPermissions()会返回0.

编辑:好的,感谢@Emil我能够更改示例以检查导致此服务的UUID:

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);
                        }
                    }
                }

BLE设备现在可以正确接收数据!

1 个答案:

答案 0 :(得分:1)

这意味着远程设备不允许您写入该特性(尽管它已在属性中设置了可写位...)

但是你不应该像这样循环遍历这些服务,只要写下你找到的第一个可写特性。而是通过uuid找到正确的服务和特性,以确保找到正确的服务和特性。