蓝牙聊天 - 将完整的传入消息作为字符串传递
我正在使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为问题是,
case MESSAGE_READ:
不仅在收到完整的Packet
时被调用,而且在收到小片段时也会被调用。因此,您应该将readMessage
放在单独的缓冲区中(即mNewBuf += readMessage
),检查mNewBuf
中是否有完整的数据包。如果是这样,您将解析您的消息,然后清除缓冲区。这对我有用。I think the problem is, that
case MESSAGE_READ:
is not only called if a completePacket
is received, it is also called if a small fragment is received. So you should place thereadMessage
in a separate buffer (i.e.mNewBuf += readMessage
) check themNewBuf
has a complete packet in it. If so, you parse your message and after that you clear your buffer. It worked for me.equals()
不应用正则表达式。如果您想匹配.*
,请使用java.util.regex
中的类来帮助您。equals()
doesn't apply regular expressions. If you want to match.*
, use classes fromjava.util.regex
to help you.我遇到了同样的问题,我不是 100% 这总是有效的,但我在 javadoc 上发现了这一点:
如果你知道你期望有多少字节,那么你可以尝试使用
但是,如果你传入的数据,这将不起作用数据的长度是可变的。
I was having the same issue, and I'm not 100% this will always work but I found this on the javadoc:
If you know how many bytes you are expecting then you could try using
However, this wouldn't work if your incoming data is variable in length.