首页 > 解决方案 > 安卓通过低功耗蓝牙接收到的信息包处理速度慢的原因是什么?

问题描述

任务是将信息从具有 BLE 4.0 的芯片以高速(至少 24 kbps)传输到 Android 设备。蓝牙规范允许它。我们使用了两种方法:写/读(我们将请求写入一个特征,从另一个特征中读取答案)和通知(芯片以 50 毫秒的频率不断发送数据包)。在写入/读取的情况下,重写和读取数据包的时间在 100 ms 范围内变化。使用 notify 时,时间设置为 50 毫秒,但 Android 正在丢包。相反,他收到了数据包的旧值,或者错过了两次并读取了下一个,尽管芯片准确地发送了带有新值的通知。我该如何解决或解决此问题?

private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
                mConnected = true;
                updateConnectionState(R.string.connected);
                invalidateOptionsMenu();
            } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
                mConnected = false;
                updateConnectionState(R.string.disconnected);
                invalidateOptionsMenu();
                clearUI();
            } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
                // Show all the supported services and characteristics on the user interface.
                //displayGattServices(mBluetoothLeService.getSupportedGattServices());
            } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
                stopT =System.currentTimeMillis();
                //double td=stopT-startT;

                time1.add(stopT - startT);
                //double td = Math;
                double sum = 0;
                for(int i =0;i<time1.size();i++) sum+= time1.get(i);
                double td = sum/time1.size();
                TextView textView3 = (TextView) findViewById(R.id.textView3);
                textView3.setText(String.valueOf(td));
                displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA));

                //for (int i = 0; i < BluetoothLeService.byteArray.length; i++) time.add(Double.valueOf(BluetoothLeService.byteArray[i]));

                float[] floatArray = new float[BluetoothLeService.byteArray.length];
                for (int i = 0; i < BluetoothLeService.byteArray.length; i++) floatArray[i] = (float)BluetoothLeService.byteArray[i];
                float[] tmp = new float[time2.length + floatArray.length];
                System.arraycopy(time2, 0, tmp, 0, time2.length);
                System.arraycopy(floatArray, 0, tmp, time2.length, floatArray.length);
                time2 = tmp;

                if (cnt1 < 51) {
                    Matr[cnt1]=floatArray;
                    cnt1++;
                }


                if (flag == 1) {
                    startT = System.currentTimeMillis();
                    //mBluetoothLeService.readCustomCharacteristic();
                    mBluetoothLeService.writeCustomCharacteristic(hex);
                }
                if(flag_notify == 1)startT = System.currentTimeMillis();
            } else if (BluetoothLeService.ACTION_CHARACTERISTIC_WRITE.equals(action)) {
                mBluetoothLeService.readCustomCharacteristic();
            }
        }
    };

private void broadcastUpdate(final String action,
                                 final BluetoothGattCharacteristic characteristic) {
        final Intent intent = new Intent(action);

        // This is special handling for the Heart Rate Measurement profile.  Data parsing is
        // carried out as per profile specifications:
        // http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml
        if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {
            int flag = characteristic.getProperties();
            int format = -1;
            if ((flag & 0x01) != 0) {
                format = BluetoothGattCharacteristic.FORMAT_UINT16;
                Log.d(TAG, "Heart rate format UINT16.");
            } else {
                format = BluetoothGattCharacteristic.FORMAT_UINT8;
                Log.d(TAG, "Heart rate format UINT8.");
            }
            final int heartRate = characteristic.getIntValue(format, 1);
            Log.d(TAG, String.format("Received heart rate: %d", heartRate));
            intent.putExtra(EXTRA_DATA, String.valueOf(heartRate));
        } else {
            // For all other profiles, writes the data formatted in HEX.
            final byte[] data = characteristic.getValue();
            byteArray =data;
            if (data != null && data.length > 0) {
                final StringBuilder stringBuilder = new StringBuilder(data.length);
                for(byte byteChar : data)
                    stringBuilder.append(String.format("%02X ", byteChar));
                intent.putExtra(EXTRA_DATA, new String(data) + "\n" + stringBuilder.toString());
            }
        }
        sendBroadcast(intent);
    }

蓝牙Gatt回调:

private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            String intentAction;
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                intentAction = ACTION_GATT_CONNECTED;
                mConnectionState = STATE_CONNECTED;
                //gatt.requestMtu(512);
                broadcastUpdate(intentAction);
                Log.i(TAG, "Connected to GATT server.");
                // Attempts to discover services after successful connection.
                Log.i(TAG, "Attempting to start service discovery:" +
                        mBluetoothGatt.discoverServices());

            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                intentAction = ACTION_GATT_DISCONNECTED;
                mConnectionState = STATE_DISCONNECTED;
                Log.i(TAG, "Disconnected from GATT server.");
                broadcastUpdate(intentAction);
            }
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
            } else {
                Log.w(TAG, "onServicesDiscovered received: " + status);
            }
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt,
                                         BluetoothGattCharacteristic characteristic,
                                         int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
            }
        }

        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt,
                                          BluetoothGattCharacteristic characteristic, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                broadcastUpdate(ACTION_CHARACTERISTIC_WRITE, characteristic);
            } else {
                Log.w(TAG, "onCharacteristicWrite received: " + status);
            }
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt,
                                            BluetoothGattCharacteristic characteristic) {
            broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
        }
    };

更新:回调函数的变化。

public void onCharacteristicChanged(BluetoothGatt gatt,
                                            BluetoothGattCharacteristic characteristic) {
            StopT = System.currentTimeMillis();
            if (cnt1 < kolvo) {
                save[cnt1]=characteristic.getValue();
                td1 [cnt1] = StopT - StartT;
                StartT = System.currentTimeMillis();

                cnt1++;
            }
            broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
        }

标签: androidbluetoothbluetooth-lowenergy

解决方案


推荐阅读