Android:通过 BLE 发送数据 > 20 字节 [英] Android: Sending data >20 bytes by BLE

查看:27
本文介绍了Android:通过 BLE 发送数据 > 20 字节的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am able to send data upto 20 bytes by connecting to an external BLE device. How do I send data greater than 20 bytes. I have read that we have to either fragment the data or split characteristic to required parts. If I assume my data is 32 bytes, could you tell me changes I need to make in my code to get this working? Following are the required snippets from my code:

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);
}

这是我用来发送数据的代码.send"函数用在下面的onclick事件中.

This is the code I used for sending the data. The "send" function is used in the following onclick event.

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 个字节.如何纠正?

When the String text is greater than 20 bytes then only the first 20 bytes are received. How to rectify this?

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

To test sending multiple characteristics I tried this:

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 的新手,所以请忽略任何天真

But I only received "Test3" i.e. the last characteristic. What mistake did I commit? I am new to BLE so please ignore any naiveness

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

After accepting answer for anyone who views this later.

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

There are two ways to accomplish this. 1. Split up your data and write in a loop as the selected answer does. 2. Split up your data and write using callback i.e. onCharacterisitcWrite(). This will save you from errors if there were any during writing.

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

But most important between the writes use a Thread.sleep(200) if you are only writing and not waiting for a response from the firmware. This will ensure that all of your data reaches. Without the sleep I was always getting the last packet. If you notice the accepted answer he has also used sleep in between.

推荐答案

BLE 允许您最多传输 20 个字节.

BLE allows you transfer maximum of 20 bytes.

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

If you want to send more than 20 bytes, you should define array byte[] to contain how many packets you want.

如果您想发送少于 160 个字符(160 个字节),下面的示例工作正常.

Following example worked fine if you want to send less than 160 characters (160 bytes).

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

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

Actually, when we are using BLE, mobile side and firmware side need to set up the Key (ex. 0x03 ...) to define the connection gate among both sides.

这个想法是:

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

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

If we send the last one, The gate is byte[1] = 0x00.

数据结构(20字节):

The data contruction (20 bytes):

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

1 - Byte 1 - Define the Gate ID : ex. Message gate ID byte[0] = 0x03.

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

2 - Byte 2 - Define the recognization : Is the last packet 0x00 or continue sending packets 0x01.

3 - Byte 3(去掉Byte 1 & Byte 2后应该是18个字节) - 在这里附上消息内容.

3 - Byte 3 (Should be 18 bytes after eliminating Byte 1 & Byte 2) - Attach the message content in here.

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

下面是一个发送多个数据包的Message的例子,每个数据包是一个20字节大小的数组.

Below is an example of sending a Message with many packets, each packet is an array of size 20 bytes.

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:通过 BLE 发送数据 > 20 字节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆