【问题标题】:Bluetooth SPP receive some the package frame can lost or?蓝牙SPP接收一些包帧会丢失还是?
【发布时间】:2015-10-19 22:18:08
【问题描述】:

我使用android示例代码进行修改。只想收到包裹 但是,我的代码只在这里修改

private final Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
        case MESSAGE_STATE_CHANGE:
            if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
            switch (msg.arg1) {
            case BluetoothChatService.STATE_CONNECTED:
                mTitle.setText(R.string.title_connected_to);
                mTitle.append(mConnectedDeviceName);
                mConversationArrayAdapter.clear();
                break;
            case BluetoothChatService.STATE_CONNECTING:
                mTitle.setText(R.string.title_connecting);
                break;
            case BluetoothChatService.STATE_LISTEN:
            case BluetoothChatService.STATE_NONE:
                mTitle.setText(R.string.title_not_connected);
                break;
            }
            break;
        case MESSAGE_WRITE:
            byte[] writeBuf = (byte[]) msg.obj;
            // construct a string from the buffer
            String writeMessage = new String(writeBuf);
            mConversationArrayAdapter.add(writeMessage);
            break;
        case MESSAGE_READ:

            byte[] readBuf = (byte[]) msg.obj;
            // construct a string from the valid bytes in the buffer
            //String readMessage = new String(readBuf, 0, msg.arg1);
            //String readMessage = BytesTrans_fill.bytesToHexString(readBuf);
            Log.d("read", BytesTrans.bytes2HexString(readBuf,msg.arg1));
            String readMessage = BytesTrans.bytes2HexString(readBuf,msg.arg1);
            ppV.setText(ppV.getText().toString() + readMessage + "★");
            break;
        case MESSAGE_DEVICE_NAME:
            // save the connected device's name
            mConnectedDeviceName = msg.getData().getString(
                    DEVICE_NAME);
            Toast.makeText(getApplicationContext(), "Connected to "
                           + mConnectedDeviceName, Toast.LENGTH_SHORT).show();
            break;
        case MESSAGE_TOAST:
            Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST),
                           Toast.LENGTH_SHORT).show();
            break;
        }
    }
};

和蓝牙聊天服务

    public void run() {
        Log.i(TAG, "BEGIN mConnectedThread");

        byte[] buffer = new byte[1024];

        int bytes;

        // Keep listening to the InputStream while connected
        while (true) {
            try {
                // Read from the InputStream
                bytes = mmInStream.read(buffer);

                // Send the obtained bytes to the UI Activity
                mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes, -1, buffer)
                        .sendToTarget();
            } catch (IOException e) {
                Log.e(TAG, "disconnected", e);
                connectionLost();
                break;
            }
        }
    }

并添加此功能

package com.example.android.BluetoothChat;

public class BytesTrans {
    public static String byte2HexString(byte b) {
        String ret = "";
            String hex = Integer.toHexString(b & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            ret += hex.toUpperCase()  + " ";
        return ret;
    }

    public static String bytes2HexString(byte[] b, int count) {
        String ret = "";
        for (int i = 0; i < count; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            ret += hex.toUpperCase() + " ";
        }
        return ret;
    }
    /*public static String String2byte(String b)
    {
        String[] ttt;
        for (int i = 0; i < b.length(); i++)
        {
            for (int j= i; j<=i+1; j++)
            {
                ttt[i] = b;
            }

        }           

        String ttmp = "";
        String tmp = "";





        ret += tmp;
    }*/
    public static int hexToTen(String b) {
        int D2 = Integer.parseInt(b,16);


        return D2;
        }
    }

但是这个程序有时甚至不会显示在我的发送包的框架中

我这样发送包裹:

aa07210820001202140934390000000000000000000000000000000000000000000297c0fe6b

但有时会收到包裹:

aa000297c0fe6b02131452470000000000000000000000000000000000000000000297c0fe6b

如何更改我的代码以接收完整包的框架

【问题讨论】:

  • 感谢您的回答,非常详细。因为这个只使用了蓝牙聊天的例子,所以我只粘贴修改的地方。我不明白,为什么这段代码会产生这个问题。直到现在我才搜索这个错误。可以教教我吗??非常感谢。

标签: android bluetooth


【解决方案1】:

您尚未显示任何蓝牙接口代码。但是,如果这主要基于 BluetoothChat 示例,那么 BluetoothChat 示例就存在一个简单的问题:基本上,当从蓝牙套接字生成 read() 并将其放入字节数组中时,该数组引用是正如您所做的那样,使用Handler 发送到 UI。实际问题是,如果 BluetoothChat 示例用于以比打字速度更快的速度接收数据,那么您会开始看到字符丢失或变得混乱,因为随后的 read() 在 UI 仍然存在时覆盖了数组读取数组以提取收到的最后一堆字符。

因此,如果您的 MESSAGE_WRITE 对象包含对您正在调用套接字 read() 的数组的引用,那么这可能就是您丢失字符的原因。因此,请尝试使用Arrays.copyOf()Message 中发送数组的副本。或者,也许您可​​以使用循环缓冲区安排。

当我使用 BluetoothChat 示例作为我的项目的基础时,我就遇到了这个问题。我个人为解决这个问题(并消除复制缓冲区等的需要)所做的是实现一种机制,通过该机制我将告诉蓝牙连接线程(包含阻塞套接字.read() 的线程),通过在方法调用中,我期望响应是多少字节(幸运的是,我正在处理的协议允许知道响应长度)。然后,连接线程仅在收到完整响应时发送Message,而不是向 UI 发送多个带有响应片段的Messages。

【讨论】:

    【解决方案2】:

    这是我的解决方案,使用 Android 聊天示例代码。这只是一种可能的解决方案。我收到了以\n 结尾的消息。我正在使用这个线程从通过蓝牙连接的 Arduino 读取消息。在 Arduino 上,我可以确保每条消息都以\n 结尾,使用Serial.println( buffer );

    我收到的所有内容都附加到现有字符串(queue 变量)。当我在这个大字符串上有整行时,我将其发送到活动并将其从queue 变量中删除。

        public void run() {
            Log.i(TAG, "BEGIN mConnectedThread");
            byte[] buffer = new byte[1024];
            int bytes, pos;
            StringBuilder queue = new StringBuilder("");
            String temp;
            // Keep listening to the InputStream while connected
            while (true) {
                try {
                    bytes = mmInStream.read(buffer);
                    if (bytes > 0) {
                        String readMessage = new String(buffer, 0, bytes);
                        queue.append(readMessage);
                        pos = queue.indexOf("\n");
                        while (pos >= 0) {
                            // Log.d("Temperatura", "indexOf() #" + pos);
                            temp = queue.substring(0, pos - 1);
                            queue.delete(0, pos + 1);
                            mHandler.obtainMessage(Constants.MESSAGE_READ, 0, 0, temp).sendToTarget();
                            pos = queue.indexOf("\n");
                        }
                    }
                } catch (IOException e) {
                    Log.e(TAG, "disconnected", e);
                    connectionLost();
                    // Start the service over to restart listening mode
                    BluetoothChatService.this.start();
                    break;
                }
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2017-12-14
      • 2015-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-12
      • 1970-01-01
      • 1970-01-01
      • 2011-10-26
      相关资源
      最近更新 更多