通知传输完成超过 20 个字节 onCharactersitcChanged BLE

Notify transmission is complete over 20 bytes onCharactersitcChanged BLE

我正在尝试从蓝牙 LE 设备获取数据,该设备发送的数据超过 20 个字节,这似乎是调用 onCharacteristicChanged 时一次可以接收的数据量的限制。

因此,如果设备根据请求发送 80 个字节的数据,则 onCharacteristicChanged 称为 four times

我的问题是,有没有办法知道何时收到所有字节,以便我可以立即请求更多数据?

编辑

这是我的代码

private final BluetoothGattCallback mGattCallback =
            new BluetoothGattCallback() {
                @Override
                public void onConnectionStateChange(BluetoothGatt gatt, int status,
                                                    int newState) {
                    String intentAction;
                    Log.d(TAG,"state:"+newState+" status:"+status+" xxx");
                    if (newState == BluetoothProfile.STATE_CONNECTED) {

                        mBluetoothGatt.requestMtu(517);

                        intentAction = ACTION_GATT_CONNECTED;
                        initState = INIT_STATE.CONNECTED;
                        //broadcastUpdate(intentAction);
                        Log.i(TAG, "Connected to GATT server. xxx");
                        Log.i(TAG, "Attempting to start service discovery xxx:" +
                                mBluetoothGatt.discoverServices());
                        Log.d(TAG,"xxx "+mBluetoothGatt.getDevice().getAddress());

                        gattConnected = true;
                        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
                            mBluetoothGatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH);
                        }

                    } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {

                        Log.i(TAG, "Disconnected from GATT server. xxx "+mBluetoothGatt.getDevice().getAddress());
                        mBluetoothGatt.close();
                        deviceList.remove(0);
                        if (deviceList.size() > 0) {

                            connectToDevice(0);
                        }
                    }
                }

                @Override
                // New services discovered
                public void onServicesDiscovered(BluetoothGatt gatt, int status) {
                    if (status == BluetoothGatt.GATT_SUCCESS) {
                        //broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
                        boolean foundMatch = false;
                        services = mBluetoothGatt.getServices();
                        for (BluetoothGattService service : services) {
                            Log.d(TAG,"Service UUID xxx:"+service.getUuid());
                            if (service.getUuid().equals(SERVICE_UUID)) {
                                foundMatch = true;
                                //*
                                mService = service;
                                mWriteCharacteristic = service.getCharacteristic(WRITE_UUID);
                                mReadCharacteristic = service.getCharacteristic(READ_UUID);
                                mCreditCharacteristic = service.getCharacteristic(WRITE_UUID_2);
                                setCharacteristicNotification(mReadCharacteristic,true);

                                newData = true;
//There is a delay for this write because a mode request is sent first from onDescriptorWrite 
                                Thread t = new Thread(new Runnable() {
                                    @Override
                                    public void run() {

                                        try {
                                            Thread.sleep(150);
                                        } catch (InterruptedException e) {
                                            e.printStackTrace();
                                        }
                                        byte[] infoRequest = {0x00, 0x02, 0x04, 0x00};
                                        write(infoRequest);
                                    }
                                });
                                t.start();
                                break;
                            }
                        }

                    } else {
                        Log.w(TAG, "onServicesDiscovered received: xxx " + status);
                    }
                }
                @Override
                public void onCharacteristicChanged(BluetoothGatt gatt,
                                                    BluetoothGattCharacteristic characteristic) {
                    //Log.d(TAG,"Charac changed..... xxx");

                    byte[] data = characteristic.getValue();
                    int dataSize = data.length;

                    System.arraycopy(data,0,rawBytes,bufferIndex,dataSize);
                    bufferIndex+=dataSize;
// The only way I can tell all the data has been received right now is to check the chunk size.
                    if (dataSize != 20) {
                        Log.d(TAG,"new data xxx");
                        newData = false;
                        bufferIndex = 0;

                        processData();
                    }
                }

                @Override
                public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
                    if (status == BluetoothGatt.GATT_SUCCESS) {
                        //if (descriptor.getCharacteristic().getUuid().equals(UUID_TARGET_CHARACTERISTIC)) {
                            Log.d(TAG, "Successfully subscribed xxx");
                        //}
                        // first thing I send is mode select request.
                        byte[] infoRequest = {0x06};
                        writeChangeMode(infoRequest);

                    } else {
                        Log.e(TAG, "Error subscribing");
                    }
                }

                @Override
                public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
                    if (status == BluetoothGatt.GATT_SUCCESS) {
                        //Write operation successful - process with next chunk!
                        Log.d(TAG,"Write successful xxx");
                    }
                }
                @Override
                public void onMtuChanged(BluetoothGatt gatt, int mtu, int status)                   {
                   super.onMtuChanged(gatt, mtu, status);
                   if ( status == BluetoothGatt.GATT_SUCCESS )
                      {
                          Log.d("TAG","call onMtuChanged "+status);
                      }
                }
            };

使用https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#requestMtu(int)尝试增加MTU。通知最大大小为 MTU - 3.

蓝牙标准中没有为 "tell when all bytes have been received" 或 "request more data" 定义程序。那是特定于应用程序的。