首页 > 解决方案 > android自定义ble服务的可写特性在发现时总是返回写权限零

问题描述

我正在 Android 上创建一个自定义 BLE 服务,它具有一个可以读/写的单一特征。代码如下所示:

public static UUID MY_SERVICE = UUID.fromString("e0ec8d9c-5e4d-470a-b87f-64f433685301");
public static UUID MY_CHARACTERISTIC    = UUID.fromString("e0ec8d9c-5e4d-470a-b87f-64f433685302");

/**
 * Return a configured {@link BluetoothGattService} instance for the
 * Custom Service.
 */
public static BluetoothGattService createCustomBleService() {
    BluetoothGattService service = new BluetoothGattService(MY_SERVICE,
            BluetoothGattService.SERVICE_TYPE_PRIMARY);

    // Current Configuration characteristic
    BluetoothGattCharacteristic characteristic = new BluetoothGattCharacteristic(MY_CHARACTERISTIC,
            BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_WRITE,
            BluetoothGattCharacteristic.PERMISSION_READ |BluetoothGattCharacteristic.PERMISSION_WRITE);


    boolean serviceAdded = service.addCharacteristic(characteristic);
    Log.i(TAG, "Building BLE service addCharacteristic returned "+serviceAdded);

    return service;
}

对 addCharacteristic(...) 的调用返回 true。服务本身是被创建的,可以被宣传的,并且服务和它的特性是可以被客户发现的。在客户端代码的其他地方,在定位所述服务的 BLE 扫描之后,运行的发现代码如下所示:

            for (BluetoothGattService service : gatt.getServices()) {

                serviceUuid = service.getUuid().toString();

                if( MY_SERVICE.toString().equals(serviceUuid)  ) {
                    List<BluetoothGattCharacteristic> gattCharacteristics = service.getCharacteristics();
                    for( BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics ) {
                        characteristicUuid = gattCharacteristic.getUuid().toString();
                        Log.d(TAG, "onServicesDiscovered() - found characteristic uuid="+characteristicUuid);
                        int cProps = gattCharacteristic.getProperties();
                        Log.d(TAG, "onServicesDiscovered() - found characteristic properties "+cProps);
                        if ((( MY_CHARACTERISTIC.toString().equals(characteristicUuid)  ))&&((cProps & BluetoothGattCharacteristic.PROPERTY_WRITE)>0)) {

                         writeCharacteristic(gatt,gattCharacteristic,"configStringLiteral");
                        }

                    }
                }

            }

正如我所提到的,当这个服务发现代码运行时,它会找到自定义服务和定义的特征。我为特征属性设置的任何值都会在客户端发现时正确显示。该特性显示为可写。

问题是特征写入总是失败,即使属性说它是可写的。

有没有人看到这个?......或者也许我正在做一些愚蠢的事情并且已经看太久了。

(顺便说一句,在运行时托管自定义服务的设备是三星 Galaxy 7,客户端是 Galaxy 6 ...反之亦然,行为相同)

标签: androidbluetooth-lowenergy

解决方案


发现服务时,不会通过 BLE 发送权限信息。因此,权限属性不应用于远程特征。

客户应该只检查特征属性以决定可以做什么。如果它收到一个错误,例如需要加密,蓝牙堆栈将开始加密,然后重试请求。

因此,特征属性是向客户声明可以用它做什么的正确方法。特征权限仅告诉本地 GATT 服务器实现它应该如何响应传入的 GATT 请求。


推荐阅读