Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 不可撤销的通知订阅获得133_Android_Bluetooth Lowenergy_Rxandroidble - Fatal编程技术网

Android 不可撤销的通知订阅获得133

Android 不可撤销的通知订阅获得133,android,bluetooth-lowenergy,rxandroidble,Android,Bluetooth Lowenergy,Rxandroidble,一部Android手机(N5X 6.0.1)正在运行一个BLE服务器,另一部(N5X O)正在订阅。 可以启用特性通知,但是,在写描述符部分,我始终得到一个133 Server.java private void createServer() { bluetoothGattServer = bluetoothManager.openGattServer(this, serverCallback); BluetoothGattService service = new Blueto

一部Android手机(N5X 6.0.1)正在运行一个BLE服务器,另一部(N5X O)正在订阅。 可以启用特性通知,但是,在写描述符部分,我始终得到一个133

Server.java

private void createServer() {
    bluetoothGattServer = bluetoothManager.openGattServer(this, serverCallback);
    BluetoothGattService service = new BluetoothGattService(Constants.SERVICE,
        BluetoothGattService.SERVICE_TYPE_PRIMARY);

    characteristic =
        new BluetoothGattCharacteristic(Constants.CHARACTERISTIC,
                BluetoothGattCharacteristic.PROPERTY_NOTIFY,
                BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattCharacteristic.PERMISSION_WRITE);

    // public static UUID DESCRIPTOR = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
    characteristic.addDescriptor(new BluetoothGattDescriptor(Constants.DESCRIPTOR,
                BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattDescriptor.PERMISSION_WRITE));

    characteristic.setWriteType(
        BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);

    service.addCharacteristic(characteristic);
    bluetoothGattServer.addService(service);
}

private BluetoothGattServerCallback serverCallback = new BluetoothGattServerCallback() {
    @Override
    public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
        super.onConnectionStateChange(device, status, newState);
        Log.d(TAG, "onConnectionStateChange " + device.getName() + " " + status + " " + newState);
        if (newState == BluetoothGatt.STATE_CONNECTED) {
            bluetoothDevice = device;
        } else if (newState == BluetoothGatt.STATE_DISCONNECTED) {
            bluetoothGattServer.cancelConnection(bluetoothDevice);
            bluetoothGattServer.close();
        }
    }
};

private void sendData(String message) {
    characteristic.setValue(message);
    bluetoothGattServer.notifyCharacteristicChanged(bluetoothDevice, characteristic, true);
}
device.establishConnection(false)
        .flatMap(bleConnection -> bleConnection.setupNotification(Constants.CHARACTERISTIC))
        .flatMap(onNotificationReceived -> onNotificationReceived)
        .subscribe(data -> {
            Log.d(TAG, "data: " + data);
        }, throwable -> {
            Log.d(TAG, "data error " + throwable);
        });
所有其他UUID都是从中创建的

Client.java

private void createServer() {
    bluetoothGattServer = bluetoothManager.openGattServer(this, serverCallback);
    BluetoothGattService service = new BluetoothGattService(Constants.SERVICE,
        BluetoothGattService.SERVICE_TYPE_PRIMARY);

    characteristic =
        new BluetoothGattCharacteristic(Constants.CHARACTERISTIC,
                BluetoothGattCharacteristic.PROPERTY_NOTIFY,
                BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattCharacteristic.PERMISSION_WRITE);

    // public static UUID DESCRIPTOR = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
    characteristic.addDescriptor(new BluetoothGattDescriptor(Constants.DESCRIPTOR,
                BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattDescriptor.PERMISSION_WRITE));

    characteristic.setWriteType(
        BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);

    service.addCharacteristic(characteristic);
    bluetoothGattServer.addService(service);
}

private BluetoothGattServerCallback serverCallback = new BluetoothGattServerCallback() {
    @Override
    public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
        super.onConnectionStateChange(device, status, newState);
        Log.d(TAG, "onConnectionStateChange " + device.getName() + " " + status + " " + newState);
        if (newState == BluetoothGatt.STATE_CONNECTED) {
            bluetoothDevice = device;
        } else if (newState == BluetoothGatt.STATE_DISCONNECTED) {
            bluetoothGattServer.cancelConnection(bluetoothDevice);
            bluetoothGattServer.close();
        }
    }
};

private void sendData(String message) {
    characteristic.setValue(message);
    bluetoothGattServer.notifyCharacteristicChanged(bluetoothDevice, characteristic, true);
}
device.establishConnection(false)
        .flatMap(bleConnection -> bleConnection.setupNotification(Constants.CHARACTERISTIC))
        .flatMap(onNotificationReceived -> onNotificationReceived)
        .subscribe(data -> {
            Log.d(TAG, "data: " + data);
        }, throwable -> {
            Log.d(TAG, "data error " + throwable);
        });
logcat

05-15 15:26:50.097 D/BluetoothGatt: setCharacteristicNotification() - uuid: 8d7dda32-3759-11e7-a919-92ebcb67fe33 enable: true
05-15 15:26:50.105 D/RxBle#Radio:   QUEUED RxBleRadioOperationDescriptorWrite(60042487)
05-15 15:26:50.110 D/RxBle#Radio: FINISHED RxBleRadioOperationServicesDiscover(231218312)
05-15 15:26:50.112 D/RxBle#Radio:  STARTED RxBleRadioOperationDescriptorWrite(60042487)
05-15 15:27:20.119 D/RxBle#Radio: FINISHED RxBleRadioOperationDescriptorWrite(60042487)
05-15 15:27:20.121 D/BluetoothGatt: setCharacteristicNotification() - uuid: 8d7dda32-3759-11e7-a919-92ebcb67fe33 enable: false
05-15 15:27:20.126 D/RxBle#BluetoothGatt: onDescriptorWrite descriptor=00002902-0000-1000-8000-00805f9b34fb status=133
05-15 15:27:20.129 D/BLE: data error BleGattDescriptorException{macAddress=42:EE:5A:C6:C1:F0, status=133 (0x85 -> https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/android-5.1.0_r1/stack/include/gatt_api.h), bleGattOperationType=BleGattOperation{description='DESCRIPTOR_WRITE'}}
注意:如果我使用本机Android API,我可以订阅和接收通知,而无需写入描述符

更新:有趣的是,在写描述符过程中(大约需要30秒才能返回错误),我能够收到
onCharacteristicChanged


update2:添加了回调和写入特征代码

蓝牙核心规范规定,如果特征支持通知,则应包含客户端特征配置描述符,并仅在使用正确值写入CCC描述符时才开始通知

在您的配置中似乎存在一个问题,表现为
status=133
。似乎您在设置
特性的属性时出错了。我假设您希望有一个可以读取、写入和设置通知的特性—在这种情况下,它看起来像:

characteristic =
    new BluetoothGattCharacteristic(Constants.CHARACTERISTIC,
            BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_NOTIFY,
            BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattCharacteristic.PERMISSION_WRITE);
编辑-请记住,如果中心请求打开通知,它将尝试编写客户端特征配置描述符。除非该请求设置为
无响应
,否则中央处理器将等待响应

正确的解决方案是向
onDescriptorWriteRequest
添加回调,并向中心服务器发送响应:

BluetoothGattServerCallback serverCallback = new BluetoothGattServerCallback() {
    // (...)

    @Override
    public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor,
                                         boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
        super.onDescriptorWriteRequest(device, requestId, descriptor, preparedWrite, responseNeeded, offset, value);

        // validate if the request is exactly what you expect if needed
        bluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, value);
    }

    // (...)
};
潜在的解决办法


一些中国制造商不符合蓝牙核心规范,并且在发送通知的特征下没有CCC描述符。如果您能够在不设置CCC的情况下获得通知,那么您可以使用兼容模式
RXbeConnection.setupNotifications(characteristic,NotificationSetupMode.COMPAT)
,尽管不建议使用该模式,并且应该对配置进行适当的修复。

建议的修复程序没有解决问题,解决方法没有。BluetoothGattServer的
设置肯定还有另一个问题。我希望两个安卓操作系统都能很好地相互配合,而解决方案只是一个解决方案。也许明天我会有时间玩Android作为服务器。谢谢您的编辑-对我来说太早了。@mbmc您能分享您的
BluetoothGattServerCallback
代码吗?我认为你没有正确地管理对中央的回应。还没有机会尝试,但会让你保持联系。就是这样!非常感谢。