当前位置: 首页 > 面试题库 >

Android:通过BLE发送大于20个字节的数据

顾俊誉
2023-03-14
问题内容

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

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事件中使用“发送”功能。

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()。如果在编写过程中出现任何错误,这将使你免于错误。

但是,如果你只是在写而不等待固件的响应,则两次写之间最重要的是使用a Thread.sleep(200)。这将确保你的所有数据都能到达。没有sleepI,我总是得到最后一个数据包。如果你注意到已接受的答案,他也会sleep在两者之间使用。


问题答案:

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

如果要发送20个以上的字节,则应定义数组byte[]以包含所需的数据包数量。

如果你要发送少于160个字符(160个字节),以下示例可以很好地工作。

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

实际上,当我们使用BLE时,移动端和固件端需要设置密钥(例如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&之后,应为18个字节Byte 2)-在此处附加消息内容。

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

下面是发送带有许多数据包的消息的示例,每个数据包是一个大小为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;
            }
        }
    }


 类似资料:
  • 我有一个关于在Android中发送字节数组的问题。 我以前试图使用Android httpclient文件上传数据损坏和超时问题 但是,我真的不知道如何使用它。。。。。。 在我的项目中,我之前使用NameValuePair列表将String类型的数据发送到Apache服务器,例如 在 post 方法中(DB_Packet是字符串变量) list name value pair = new Arra

  • 出于某些原因,我需要通过服务器套接字分别发送多个字节数组,客户端套接字将接收这些字节数组。发送字节数组后,发现客户端套接字接收的字节数组与服务器套接字接收的字节数组不相等。如果我使用ObjectOutputStream和ObjectInputStream,那么一切都很好,但是根据我的需要,我不能使用ObjectOutputStream和ObjectInputStream,因为我的服务器需要连接两个

  • 您好,我需要将以下内容写入我的BLE设备,它实际上使设备能够发送回数据或通知值。但是,在多次尝试和更改要发送的数据类型后,实际上是这样的。 我无法启用该设备。我知道我需要使用字节数组,但我不知道如何将这些添加到字节数组中 它根本不起作用。

  • 我需要通过Java socket发送一个文本消息到服务器,然后发送一个字节数组,然后是一个字符串等等。到目前为止,我所开发的内容还在工作,但客户端只读取发送的第一个字符串。 从服务器端:我使用发送字节数组,使用发送字符串。 问题是客户机和服务器不同步,我的意思是服务器发送字符串然后字节数组然后字符串,而不等待客户机消耗每个需要的字节。 我的意思是情况不是这样的:

  • 问题内容: 我正在使用Java应用程序,需要通过套接字连接尽快将500,000个整数的数组从一台Android手机发送到另一台Android手机。无论是使用ObjectOutputStreams,ByteBuffers还是低级的掩码和移位转换,主要的瓶颈似乎都是在转换整数,以便套接字可以使用它们。通过套接字从一个Java应用程序向另一个Java应用程序发送int []的最快方法是什么? 这是到目前

  • 问题内容: 我有一个内置的javascript,它可以执行以下操作:通过ajax-> php-> sql获取内容,并在单击内容后在index.php上显示它,将显示新内容。 现在,我想拥有一个在将内容单击到php之后发送数据的函数,该函数将在db中执行某些操作。如何创建将发送数据的功能?谢谢! 这是我的显示内容的代码: }); }` 问题答案: 您可以通过在jQuery.ajax 设置中包含值,将