我每次读取大于一个的字节缓冲区时总是遇到问题。这是因为无法保证您正确接收到所有字节。我的解决方法是一次一个字节地重复调用 read 并填写我的缓冲区。这样,如果我的任何字节没有被读取,就会在我的 connectedThread 的 I/O 捕获部分中捕获它,并且可以选择按照我的意愿处理它。
连接线程示例
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
// You can define this buffer to be 1024 or anything you like
buffer = new byte[3];
mmOutStream.write(253);
bytes = mmInStream.read(buffer,0,1);
mmOutStream.write(254);
bytes = mmInStream.read(buffer,1,1);
mmOutStream.write(255);
bytes = mmInStream.read(buffer,2,1);
mHandler.obtainMessage(MESSAGE_READ, buffer).sendToTarget();
}
catch (IOException e) {
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) { }
}
}
在这种情况下,我使用了一个无符号字节数组来表示 0-255 之间的整数。此外,我使用值 255-253 作为命令告诉我的 Arduino 向我发送某些类型的信息。您不必设置任何值来表示对 arduino 的命令,相反,您可以告诉 arduino 循环遍历它每次收到信息请求时需要发送的值。我发现这是确认收到的字节数的唯一方法之一(即byte[] buffer 的大小)。尽管在这种情况下,我没有在 connectedThread 的 catch 语句中添加任何内容,但您可以添加在那里读取命令以确认您收到一个字节。
消息处理程序
这是我如何处理 readBuffer...
/*
* Bluetooth Handler Method
*/
ConnectedThread connectedThread;
Handler mHandler = new Handler(){
public void handleMessage(Message msg){
super.handleMessage(msg);
switch(msg.what){
case SUCCESS_CONNECT:
// Do Something;
Toast.makeText(getActivity(),"CONNECTED",Toast.LENGTH_SHORT).show();
connectedThread = new ConnectedThread((BluetoothSocket)msg.obj);
listView.setVisibility(View.GONE);
connectedThread.start();
break;
case MESSAGE_READ:
byte[] readBuf = (byte[])msg.obj;
int tempInt = byteToInt(readBuf[0]);
int speedInt = byteToInt(readBuf[1]);
int cadenceInt = byteToInt(readBuf[2]);
EditText temperatureData = (EditText)getActivity().findViewById(R.id.temperatureData);
temperatureData.setText(Integer.toString(tempInt) + " C" );
EditText cadenceData = (EditText)getActivity().findViewById(R.id.cadence);
cadenceData.setText(Integer.toString(cadenceInt) + " rpm");
EditText speedData = (EditText)getActivity().findViewById(R.id.speed_data);
speedData.setText(Integer.toString(speedInt) + " kph");
}
}
};
在这种情况下,我在手机上显示实时传感器数据。但是你真的可以做任何事情。
希望有所帮助。