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

标签 java android bluetooth-lowenergy

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

因此,如果设备根据请求发送 80 字节的数据,则 onCharacteristicChanged 会被调用四次

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

编辑

这是我的代码

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

蓝牙标准中没有定义“告知何时已接收到所有字节”或“请求更多数据”的过程。这是特定于应用程序的。

关于java - 通知传输已完成超过 20 个字节 onCharactersitcChanged BLE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60241777/

相关文章:

android - 无法在 if 语句中启动 Activity ?

swift - 我想通过 BLE 设备使用 ANCS 回复 WhatsApp 通知

android - BLE扫描记录说明

java - 从值的 ArrayList 构建 boolean 逻辑树

java - if 语句中的数学问题

java - Android 与 PC 上的 Java : Different HttpResponse?

安卓下载远程内容

java - 由 : java. lang.ArrayIndexOutOfBoundsException 引起:数组索引超出范围:0

java - 将 JDA Discord 机器人上传到 heroku

ios - 核心蓝牙 : What is the lifetime of unique UUIDs