java - Android:通过 BLE 发送数据 >20 字节

标签 java android bluetooth-lowenergy

通过连接到外部 BLE 设备,我可以发送最多 20 个字节的数据。如何发送大于 20 字节的数据。我读过我们必须将数据分段或将特征拆分为所需的部分。如果我假设我的数据是 32 字节,你能告诉我我需要在代码中进行哪些更改才能使其正常工作吗?以下是我的代码中所需的 fragment :

public boolean send(byte[] data) {
    if (mBluetoothGatt == null || mBluetoothGattService == null) {
        Log.w(TAG, "BluetoothGatt not initialized");
        return false;
    }

    BluetoothGattCharacteristic characteristic =
            mBluetoothGattService.getCharacteristic(UUID_SEND);

    if (characteristic == null) {
        Log.w(TAG, "Send characteristic not found");
        return false;
    }

    characteristic.setValue(data);
    characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
    return mBluetoothGatt.writeCharacteristic(characteristic);
}

这是我用于发送数据的代码。下面的onclick事件中使用了“send”函数。

sendValueButton = (Button) findViewById(R.id.sendValue);
    sendValueButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String text = dataEdit.getText().toString();                           
            yableeService.send(text.getBytes());
        }
    });

String text 大于 20 个字节时,只接收前 20 个字节。如何解决这个问题?

为了测试发送多个特征,我尝试了这个:

sendValueButton = (Button) findViewById(R.id.sendValue);
sendValueButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        String text = "Test1";                           
        yableeService.send(text.getBytes());

        text = "Test2";                           
        yableeService.send(text.getBytes());

        text = "Test3";                           
        yableeService.send(text.getBytes());
    }
});

但我只收到“Test3”,即最后一个特征。我犯了什么错误?我是 BLE 新手,所以请忽略任何幼稚

编辑:

接受回答后供以后查看此内容的任何人使用。

两种方法可以实现这一点。 1.拆分您的数据并像所选答案一样循环写入。 2. 拆分数据并使用回调写入,即 onCharacterisitcWrite()。如果在编写过程中有任何错误,这将使您免于出错。

最重要的如果您只是在写而不是等待来自固件。这将确保您的所有数据都能到达。没有 sleep 我总是得到最后一个数据包。如果您注意到接受的答案,他也在两者之间使用了 sleep

最佳答案

BLE 最多允许传输 20 个字节。

如果你想发送超过 20 个字节,你应该定义数组 byte[] 来包含你想要多少个数据包。

如果您想发送少于 160 个字符(160 个字节),以下示例可以正常工作。

p/s :根据需要编辑以下内容。不要完全跟着我。

实际上,当我们使用BLE时,移动端和固件端需要设置Key(例如0x03 ...)来定义双方之间的连接门。

想法是:

  • 当我们继续传输数据包时,不是最后一个。门是byte[1] = 0x01

  • 如果我们发送最后一个,门是byte[1] = 0x00

数据构造(20字节):

1 - Byte 1 - 定义 Gate ID :例如。消息门 ID byte[0] = 0x03.

2 - Byte 2 - 定义recognization:是最后一个包0x00还是继续发送包0x01 .

3 - Byte 3(去掉Byte 1 & Byte 2后应该是18个字节) - 在此附加消息内容。

请在阅读下面的代码之前理解我的逻辑。

下面是一个发送带有多个数据包的消息的示例,每个数据包是一个大小为 20 字节的数组。

private void sendMessage(BluetoothGattCharacteristic characteristic, String CHARACTERS){
        byte[] initial_packet = new byte[3];
        /**
         * Indicate byte
         */
        initial_packet[0] = BLE.INITIAL_MESSAGE_PACKET;
        if (Long.valueOf(
                String.valueOf(CHARACTERS.length() + initial_packet.length))
                > BLE.DEFAULT_BYTES_VIA_BLE) {
            sendingContinuePacket(characteristic, initial_packet, CHARACTERS);
        } else {
            sendingLastPacket(characteristic, initial_packet, CHARACTERS);
        }
    }

private void sendingContinuePacket(BluetoothGattCharacteristic characteristic,
            byte[] initial_packet, String CHARACTERS){
        /**
         * TODO If data length > Default data can sent via BLE : 20 bytes
         */
        // Check the data length is large how many times with Default Data (BLE)
        int times = Byte.valueOf(String.valueOf(
                CHARACTERS.length() / BLE.DEFAULT_BYTES_IN_CONTINUE_PACKET));

        Log.i(TAG, "CHARACTERS.length() " + CHARACTERS.length());
        Log.i(TAG, "times " + times);

        // TODO
        // 100 : Success
        // 101 : Error
        byte[] sending_continue_hex = new byte[BLE.DEFAULT_BYTES_IN_CONTINUE_PACKET];
        for (int time = 0; time <= times; time++) {
            /**
             * Wait second before sending continue packet 
             */
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            if (time == times) {
                Log.i(TAG, "LAST PACKET ");

                /**
                 * If you do not have enough characters to send continue packet,
                 * This is the last packet that will be sent to the band
                 */

                /**
                 * Packet length byte :
                 */
                /**
                 * Length of last packet
                 */
                int character_length = CHARACTERS.length()
                        - BLE.DEFAULT_BYTES_IN_CONTINUE_PACKET*times;

                initial_packet[1] = Byte.valueOf(String.valueOf(character_length
                        + BLE.INITIAL_MESSAGE_PACKET_LENGTH));
                initial_packet[2] = BLE.SENDING_LAST_PACKET;

                Log.i(TAG, "character_length " + character_length);

                /**
                 * Message
                 */
                // Hex file
                byte[] sending_last_hex = new byte[character_length];

                // Hex file : Get next bytes
                for (int i = 0; i < sending_last_hex.length; i++) {
                    sending_last_hex[i] = 
                            CHARACTERS.getBytes()[sending_continue_hex.length*time + i];
                }

                // Merge byte[]
                byte[] last_packet = 
                        new byte[character_length + BLE.INITIAL_MESSAGE_PACKET_LENGTH];
                System.arraycopy(initial_packet, 0, last_packet,
                        0, initial_packet.length);
                System.arraycopy(sending_last_hex, 0, last_packet, 
                        initial_packet.length, sending_last_hex.length);

                // Set value for characteristic
                characteristic.setValue(last_packet);
            } else {
                Log.i(TAG, "CONTINUE PACKET ");
                /**
                 * If you have enough characters to send continue packet,
                 * This is the continue packet that will be sent to the band
                 */
                /**
                 * Packet length byte
                 */
                int character_length = sending_continue_hex.length;

                /**
                 * TODO Default Length : 20 Bytes
                 */
                initial_packet[1] = Byte.valueOf(String.valueOf(
                        character_length + BLE.INITIAL_MESSAGE_PACKET_LENGTH));

                /**
                 * If sent data length > 20 bytes (Default : BLE allow send 20 bytes one time)
                 * -> set 01 : continue sending next packet
                 * else or if after sent until data length < 20 bytes
                 * -> set 00 : last packet
                 */
                initial_packet[2] = BLE.SENDING_CONTINUE_PACKET;
                /**
                 * Message
                 */
                // Hex file : Get first 17 bytes
                for (int i = 0; i < sending_continue_hex.length; i++) {
                    Log.i(TAG, "Send stt : " 
                            + (sending_continue_hex.length*time + i));

                    // Get next bytes
                    sending_continue_hex[i] = 
                            CHARACTERS.getBytes()[sending_continue_hex.length*time + i];
                }

                // Merge byte[]
                byte[] sending_continue_packet = 
                        new byte[character_length + BLE.INITIAL_MESSAGE_PACKET_LENGTH];
                System.arraycopy(initial_packet, 0, sending_continue_packet, 
                        0, initial_packet.length);
                System.arraycopy(sending_continue_hex, 0, sending_continue_packet, 
                        initial_packet.length, sending_continue_hex.length);

                // Set value for characteristic
                characteristic.setValue(sending_continue_packet);
            }

            // Write characteristic via BLE
            mBluetoothGatt.writeCharacteristic(characteristic);
        }
    }

public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic,
            String data) {
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
            Log.w(TAG, "BluetoothAdapter not initialized");
            return false;
        }

        if (ActivityBLEController.IS_FIRST_TIME) {
            /**
             * In the first time, 
             * should send the Title
             */
            byte[] merge_title = sendTitle(data);

            // Set value for characteristic
            characteristic.setValue(merge_title);

            // Write characteristic via BLE
            mBluetoothGatt.writeCharacteristic(characteristic);

            // Reset
            ActivityBLEController.IS_FIRST_TIME = false;

            return true;
        } else {
            /**
             * In the second time, 
             * should send the Message
             */
            if (data.length() <= BLE.LIMIT_CHARACTERS) {
                sendMessage(characteristic, data);

                // Reset
                ActivityBLEController.IS_FIRST_TIME = true; 

                return true;
            } else {
                // Typed character
                typed_character = data.length();

                return false;
            }
        }
    }

关于java - Android:通过 BLE 发送数据 >20 字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24135682/

相关文章:

c++ - 如何将名称和 ID 属性添加到自定义 BLE 特性 C++

java - 字符串数组中的随机元素

java - 如何借助 php-java 桥将 java.util.Date 传递给 Java 库

android - Greendroid导入

ios - XCode:如何通过 UUID 连接到 BLE 外设?

java - 如何将数据传输到连接的蓝牙 LE 设备

java - 比较字符串的不同方法

java - 从 res 文件夹加载文件时出现 NullPointerException - Java

android - 检查文件夹是否为空(内部存储)

android - 检查是否已读取新的 SMS