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) {
Log.e(TAG, "Error connecting IO streams.");
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
if ((bytes = mmInStream.read(buffer)) > 0) {
//Send the obtained bytes to the UI activity
//mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget();
Log.i(TAG, "Read (" + bytes + ") bytes.");
String readBytesStr = new String(buffer, 0, bytes, "ASCII");
Log.i(TAG, "Bytes from stream (" + bytes + "): " + readBytesStr);
}
} catch (IOException e) {
Log.i(TAG, "Exception occurred: stopped listening to stream.");
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) {
Log.e(TAG, "ConnectedThread(): Exception in write()");
}
String temp = new String(bytes);
Log.i(TAG, "Wrote: " + temp);
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "ConnectedThread(): Exception in cancel()");
}
}
}
// Connecting as a client
// http://developer.android.com/guide/topics/connectivity/bluetooth.html#ConnectingAsAClient
private class ConnectThread extends Thread {
private /*final*/ BluetoothSocket mmSocket;
private /*final*/ BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp = null;
mmDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
// MY_UUID is the app's UUID string, also used by the server code TODO
tmp = device.createRfcommSocketToServiceRecord(mUUID);
} catch (IOException e) {
Log.e(TAG, "ConnectThread() : Unable to create temp socket.");
}
mmSocket = tmp;
Log.i(TAG, "Socket obtained (Connect): " + mmSocket.toString());
}
public void run() {
// Cancel discovery because it will slow down the connection
mBluetoothAdapter.cancelDiscovery();
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
Log.e(TAG, "ConnectThread().run() : Unable to connect.");
try {
mmSocket.close();
} catch (IOException closeException) {
Log.e(TAG, "ConnectThread().run() : Unable to close socket.");
}
return;
}
// Do work to manage the connection (in a separate thread) TODO
Log.i(TAG, "ConnectThread().run() : Ready to manage connection.");
mConnectedSocket = mmSocket;
manageConnectedSocket(mConnectedSocket);
}
private void manageConnectedSocket(BluetoothSocket mmSocket) {
mConnectedThread = new ConnectedThread(mmSocket);
mConnectedThread.start();
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
mmSocket = null;
Log.i(TAG, "ConnectThread().cancel() successful");
}
}
我使用基于Android's example for managing a bluetooth connection的代码连接和读取/写入蓝牙模块的数据。如果我记录首先读取的字节数,我只能正确读取数据:
Log.i(TAG, "Read (" + bytes + ") bytes.");
如果没有该行,下一个日志将不显示任何内容。
Log.i(TAG, "Bytes from stream (" + bytes + "): " + readBytesStr);
用作业替换第一个日志没有帮助。
int numReadBytes = bytes;
基于对this问题的回答,我也尝试使用DataInputStream的readFully(),但它从未完全读取预期的输入(尽管有足够大的缓冲区)。
为什么日志能够正常工作?