为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

拉莫斯之舞 2019-11-11 15:44:16
通过连接到外部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在两者之间使用。
查看完整描述

3 回答

?
噜噜哒

TA贡献1784条经验 获得超7个赞

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;

            }

        }

    }


查看完整回答
反对 回复 2019-11-11
?
慕码人8056858

TA贡献1803条经验 获得超6个赞

在Lollipop上,您最多可以发送512字节。您需要使用 BluetoothGatt.requestMtu()512的值。此外,正如@Devunwired提到的那样,您需要等到之前的任何操作完成后才能调用此函数。


查看完整回答
反对 回复 2019-11-11
  • 3 回答
  • 0 关注
  • 2914 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信