android - 被 BluetoothGattServerCallback#onCharacteristicWriteRequest 搞糊涂了

标签 android

被 Android 弄糊涂了 BluetoothGattServerCallback#onCharacteristicWriteRequest方法。

  1. 对于参数preparedWrite,我原以为写操作应该由我来负责,回调如何知道我应该在什么时候对消息进行排队?

  2. 文档说应用程序必须调用 BluetoothGattServer.sendResponse(BluetoothDevice, int, int, int, byte[]) 来完成请求。,如果 responseNeeded 是假的?

  3. 调用 BluetoothGattServer#sendResponse(BluetoothDevice, int, int, int, byte[]) 似乎总是返回请求中的值,无论我将什么设置为 value。是预期的吗?

最佳答案

preparedWrite 用于支持长写(大于 MTU)。

BluetoothGattServerCallback#onCharacteristicWriteRequestBluetoothGattServerCallback#onExecuteWrite 结合使用以重组对等设备发送的 fragment 数据。回答您的问题:

  1. 参数preparedWrite在接收到传入数据的 fragment 时为真,即数据需要排队直到更多数据到达。 BluetoothGattServerCallback#onExecuteWrite 将在接收到最终 fragment 并且可以完全组装发送的特征值后调用。

  2. 如果 responseNeeded 为 false,则不要调用 BluetoothGattServer.sendResponse(BluetoothDevice, int, int, int, byte[])

  3. 只需发送一个空的

    下面是一个onCharacteristicWriteRequest的例子:

                @Override
                public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
                    super.onCharacteristicWriteRequest(device, requestId, characteristic, preparedWrite, responseNeeded, offset, value);
                    Log.d("SVC", "BluetoothGattServerCallback.onCharacteristicWriteRequest with " + value.length + " bytes");
                    if(preparedWrite) {
                        handleInputFragment(device, characteristic.getUuid(), value);
                    } else {
                        handleInputMessage(device, characteristic.getUuid(), value);
                    }
                    if(responseNeeded) {
                        Log.d("SVC", "sending response to write request for characteristic: " + characteristic.getUuid());
                        if(!gattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, new byte[0])) {
                            Log.e("SVC", "response to characteristic write request failed");
                        }
                    }
                }

onExecuteWrite

                @Override
                public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) {
                    Log.d("SVC", "BluetoothGattServerCallback.onExecuteWrite " + (execute ? "execute" : "cancelled"));
                    super.onExecuteWrite(device, requestId, execute);
                    Iterator<InputBuffer> itr = inputBuffers.iterator();
                    while(itr.hasNext()) {
                        InputBuffer buf = itr.next();
                        if(buf.device.equals(device)) {
                            itr.remove();
                            if(execute) {
                                ByteArrayOutputStream os = new ByteArrayOutputStream();
                                for (byte[] b : buf.bytes) {
                                    os.write(b, 0, b.length);
                                }
                                handleInputMessage(device, buf.characteristicUuid, os.toByteArray());
                            }
                        }
                    }
               }

InputBuffer机制的实现是这样的

    private class InputBuffer {
        final BluetoothDevice device;
        final UUID characteristicUuid;
        final List<byte[]> bytes;

        InputBuffer(BluetoothDevice device, UUID characteristicUuid, byte[] value) {
            this.device = device;
            this.characteristicUuid = characteristicUuid;
            this.bytes = new ArrayList<>();
            this.bytes.add(value);
        }
    }

    private List<InputBuffer> inputBuffers = new LinkedList<>();

    private void handleInputFragment(BluetoothDevice device, UUID characteristicUuid, byte[] value) {
        Log.d("SVC", "handling input Fragment");
        for(InputBuffer buf : inputBuffers) {
            if(buf.device.equals(device)) {
                buf.bytes.add(value);
                return;
            }
        }
        inputBuffers.add(new InputBuffer(device, characteristicUuid, value));
    }

handleInputMessage 的实现是特定于应用程序的。

关于android - 被 BluetoothGattServerCallback#onCharacteristicWriteRequest 搞糊涂了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50730896/

相关文章:

java - 非法状态异常 : Could not execute method for android:onClick when trying to migrate to another page?

java - 打开跟踪文件时出错:没有这样的文件或目录| java.lang.ClassNotFoundException:net.sourceforge.jtds.jdbc.Driver

android - 我想在 Box API v2 for Android 中检索当前用户的用户信息

android - 在 Marshmallow 上以编程方式安装 APK

java - 使用不确定元素对 json 数据建模

java - 启用 Google 位置服务 Intent

Android Mapbox 地理编码

android - 适用于 Android 的滑动切换

java - Android:新手正确使用ndk?

java - Sugar ORM 库数据未正确检索