蓝牙聊天 - 将完整的传入消息作为字符串传递

发布于 2024-10-02 12:18:16 字数 3719 浏览 5 评论 0原文

我正在使用 Android 网站上的蓝牙聊天示例应用程序。我想将完整的传入消息(消息格式包含在下面的代码中,因为该网站正在为我解析消息,这也是我在代码中的工作)到一个删除标签并提取消息名称和值的函数, 是来自蓝牙聊天应用程序的代码(来自 Android 网站)。

使用它来执行进一步的操作。 readMessage 字符串(在 switch case Message_Read 中)发送选定的字符并省略一些特殊字符,以下 以我在代码中提到的格式接收完整的消息。它会显示在多行中,并且许多字符会被删除。

// The Handler that gets information back from the BluetoothChatService

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("Me:  " + 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);
            mConversationArrayAdapter.add(mConnectedDeviceName+":  " + readMessage);                 

            //Make sure there is a received message. Extract it's name and value
            //int msgLen = readMessage.length();
            //if( msgLen!= 0)
            // Message format is <MSG><N>shiftDirection<!N><V>1<!V><!MSG> 
            if (readBuf.equals("<MSG><N>.*<!N><V>.*<!V><!MSG>"))  
             extractData(readMessage); 
            else mTitle.setText(R.string.floor_it);

            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);
                //String Incoming = new String(buffer);
                //Pass "Incoming" instead of "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;
            }
        }
    }

I am using Bluetooth Chat sample app from Android website. I want to pass the complete incoming message, (message format included in the code below as this website is parsing the message for me which is my job in the code as well, to a function which removes the tags and extracts message name and value and uses it for further action. The readMessage string (in the switch case Message_Read) sends selected characters and omits few special characters. Following is the code from Bluetooth Chat app (from Android website).

I am not able to receive the complete message in the format which I have mentioned in the code. It gets displayed in multiple lines and many characters get deleted. Any suggestion why this is happening?

// The Handler that gets information back from the BluetoothChatService

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("Me:  " + 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);
            mConversationArrayAdapter.add(mConnectedDeviceName+":  " + readMessage);                 

            //Make sure there is a received message. Extract it's name and value
            //int msgLen = readMessage.length();
            //if( msgLen!= 0)
            // Message format is <MSG><N>shiftDirection<!N><V>1<!V><!MSG> 
            if (readBuf.equals("<MSG><N>.*<!N><V>.*<!V><!MSG>"))  
             extractData(readMessage); 
            else mTitle.setText(R.string.floor_it);

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

The part of the code which reads the incoming stream of bytes into a buffer and passes the buffer object for display.

    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);
                //String Incoming = new String(buffer);
                //Pass "Incoming" instead of "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;
            }
        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

魂ガ小子 2024-10-09 12:18:16

我认为问题是, case MESSAGE_READ: 不仅在收到完整的 Packet 时被调用,而且在收到小片段时也会被调用。因此,您应该将readMessage放在单独的缓冲区中(即mNewBuf += readMessage),检查mNewBuf中是否有完整的数据包。如果是这样,您将解析您的消息,然后清除缓冲区。这对我有用。

I think the problem is, that case MESSAGE_READ: is not only called if a complete Packet is received, it is also called if a small fragment is received. So you should place the readMessage in a separate buffer (i.e. mNewBuf += readMessage) check the mNewBuf has a complete packet in it. If so, you parse your message and after that you clear your buffer. It worked for me.

心如狂蝶 2024-10-09 12:18:16
if (readBuf.equals("<MSG><N>.*<!N><V>.*<!V><!MSG>"))  
         extractData(readMessage); 
  • equals() 不应用正则表达式。如果您想匹配 .*,请使用 java.util.regex 中的类来帮助您。
if (readBuf.equals("<MSG><N>.*<!N><V>.*<!V><!MSG>"))  
         extractData(readMessage); 
  • equals() doesn't apply regular expressions. If you want to match .*, use classes from java.util.regex to help you.
哆啦不做梦 2024-10-09 12:18:16

我遇到了同样的问题,我不是 100% 这总是有效的,但我在 javadoc 上发现了这一点:

read(byte[] b, int off, int len) 
      Reads up to len bytes of data from the input stream into an array of bytes.

如果你知道你期望有多少字节,那么你可以尝试使用

bytes = mmInStream.read(buffer, 0, lengthYouWant);

但是,如果你传入的数据,这将不起作用数据的长度是可变的。

I was having the same issue, and I'm not 100% this will always work but I found this on the javadoc:

read(byte[] b, int off, int len) 
      Reads up to len bytes of data from the input stream into an array of bytes.

If you know how many bytes you are expecting then you could try using

bytes = mmInStream.read(buffer, 0, lengthYouWant);

However, this wouldn't work if your incoming data is variable in length.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文