java - 我的智能手机上只收到一个数据包

标签 java android-studio bluetooth-lowenergy

对于一个项目,我想通过 BLE 4.2(使用 DLE)发送加速度数据。一个加速数据包由 81 个值组成(每个值 24 位,总共 243 个字节)。我的目标是发送 18 个数据包(1458 个加速数据包或 4374 字节)。我使用 Samsung Galaxy A3 2017 Edition 作为中央设备,使用微 Controller (nRF52832dk) 作为外围设备。所有数据包发送完毕后,与智能手机的连接将终止,并记录新的 1458 加速数据包。之后,RTC 会激活 nRF52832dk 上的 sleep 模式 1 分钟。 1 分钟后,nRF52832dk 将发布与智能手机的新连接广告。下图说明了这个问题:

https://ibb.co/Syb4GDg

nRF52832dk 上的软件运行良好。我能够记录数据、进入休眠模式、1 分钟后唤醒并通告新连接。我的问题是软件应用程序。我使用这些教程:

https://github.com/googlesamples/android-BluetoothLeGatt

https://developer.android.com/guide/topics/connectivity/bluetooth-le

在BluetoothLeGatt中我改变了:

mBluetoothGatt = device.connectGatt(this, true, mGattCallback);

当第二个参数为 true 时,智能手机可以自动连接。这工作正常(对于与 nRF 的第一次连接)

原来是: mBluetoothGatt = device.connectGatt(this, false, mGattCallback);

一旦建立连接,GATT 处理程序就会调用回调例程。

    // Implements callback methods for GATT events that the app cares about.  For example,
    // connection change and services discovered.
    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;
                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
        // New services discovered
        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
        // Result of a characteristic read operation
        public void onCharacteristicRead(BluetoothGatt gatt,
                                         BluetoothGattCharacteristic characteristic,
                                         int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
            }
        }

        @Override
        // Change in the characteristic
        public void onCharacteristicChanged(BluetoothGatt gatt,
                                            BluetoothGattCharacteristic characteristic) {
            broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
        }
    }; </i>

建立连接并收到第一个数据包后,我进入广播更新

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

        // This is special handling for the nRF52 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_NRF.equals(characteristic.getUuid())) {

            byte[] data = characteristic.getValue();                                                    
            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());
            }

        } else {
            // For all other profiles, writes the data formatted in HEX.
            final byte[] data = characteristic.getValue();
            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);
    }

现在我遇到了两个问题(在更改代码之前我也遇到了同样的两个问题)。

第一个问题: 我的第一个问题是,我只收到 18 个 BLE 包中的一个(第一个)。

第二个问题: 我的第一个问题也导致了我的第二个问题。应用程序无法识别与 nRF52832dk 的连接已终止。

我还有一个问题。到底是什么作用

结束广播(意图);

最佳答案

这篇文章很复杂,我想你的意思是你无法接收nrf52数据。

  1. 您需要检查 nrf52 支持多少个 MTU,BLE 保护最大值为“247”,有效数据长度为“244”,有效长度为 (DEVICE_MTU - OPCODE_LENGTH(1) - HANDLE_LENGTH(2));

  2. 所以正如你所说你想要接收 2474 字节,它至少是 17 倍。

  3. android当前的进程是onCharacteristicChanged -> onCharacteristicRead

  4. 如果您想触发 onCharacteristicChanged,您需要打开远程设备通知,如下所示:

    private void EnableNotification(BluetoothGattDescriptor d, BluetoothGatt gatt)
    {
        gatt.SetCharacteristicNotification(d.Characteristic, true);
        d.SetValue(new byte[] { 1, 1 });
        gatt.WriteDescriptor(d);
    }
    

关于java - 我的智能手机上只收到一个数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57769186/

相关文章:

java - 导入 java.awt.* 错误

java - 匹配 scrypt 的正则表达式

android-studio - Android Studio 删除行和重复行快捷方式

bluetooth - 如何使用基于HM-10蓝牙模块的BLE Shield?

ios - CoreBluetooth和iBeacon : any conflicts?

java - 设置通知后写入功能不起作用

java - 当我在 android studio 中将库导入为模块时,我在类里面遇到了红色

java - 在 Java 中声明对象时,(类名)是什么意思 - Android

android-studio - 如何让 Android Studio 始终在 "find window"中打开搜索结果?

android - 升级Android Studio 3.1.2后,ProGuard配置解析器报错?