0
每當我嘗試通過創建的套接字寫東西,我在連接的線程上得到一個斷管異常,我遵循Android開發頁面上的示例(創建三個不同的線程,連接,接受和接收數據),但由於某種原因,每次我想送點東西線接近我得到一個套接字關閉的異常,與藍牙連接
我創建的類如下:
public class BluetoothService {
private static final UUID MY_UUID =
UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
private static final String NAME = "Guess the Movie";
private BluetoothAdapter mBluetoothAdapter;
private Context context;
private AcceptThread mAcceptThread;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;
public BluetoothService(Context context) {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
this.context = context;
}
private void manageConnectedSocket(BluetoothSocket socket, BluetoothDevice device) {
// TODO: 25/06/2017
Log.d(TAG, "socket received" + socket);
connected(socket, device);
}
public synchronized void connect(BluetoothDevice device) {
Log.d(TAG, "connect to: " + device);
// Cancel any thread attempting to make a connection
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
// Start the thread to connect with the given device
mConnectThread = new ConnectThread(device);
mConnectThread.start();
// Update UI title
//updateUserInterfaceTitle();
}
public synchronized void start() {
Log.d(TAG, "start");
// Cancel any thread attempting to make a connection
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
// Start the thread to listen on a BluetoothServerSocket
if (mAcceptThread == null) {
mAcceptThread = new AcceptThread();
mAcceptThread.start();
}
// Update UI title
//updateUserInterfaceTitle();
}
public synchronized void connected(BluetoothSocket socket, BluetoothDevice
device) {
Log.d(TAG, "connected() called");
// Cancel the thread that completed the connection
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
// Cancel the accept thread because we only want to connect to one device
if (mAcceptThread != null) {
mAcceptThread.cancel();
mAcceptThread = null;
}
// Start the thread to manage the connection and perform transmissions
mConnectedThread = new ConnectedThread(socket);
mConnectedThread.start();
Log.d(TAG, "connected() finished");
// Send the name of the connected device back to the UI Activity
/*
Message msg = mHandler.obtainMessage(Constants.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(Constants.DEVICE_NAME, device.getName());
msg.setData(bundle);
mHandler.sendMessage(msg);
// Update UI title
updateUserInterfaceTitle();
*/
}
public void write(byte[] out) {
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
r = mConnectedThread;
}
// Perform the write unsynchronized
Log.d(TAG, "write() called");
r.write(out);
Log.d(TAG, "write() finished");
}
private class AcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket;
public AcceptThread() {
// Use a temporary object that is later assigned to mmServerSocket,
// because mmServerSocket is final
BluetoothServerSocket tmp = null;
try {
// MY_UUID is the app's UUID string, also used by the client code
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
} catch (IOException e) {
}
mmServerSocket = tmp;
}
public void run() {
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (true) {
try {
socket = mmServerSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if (socket != null) {
// Do work to manage the connection (in a separate thread)
manageConnectedSocket(socket, socket.getRemoteDevice());
try {
mmServerSocket.close();
} catch (IOException e) {
Log.e(TAG, "Could not close unwanted socket", e);
}
break;
}
}
}
/**
* Will cancel the listening socket, and cause the thread to finish
*/
public void cancel() {
try {
mmServerSocket.close();
} catch (IOException e) {
}
}
}
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
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
}
mmSocket = tmp;
}
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
try {
mmSocket.close();
} catch (IOException closeException) {
}
return;
}
// Do work to manage the connection (in a separate thread)
manageConnectedSocket(mmSocket, mmDevice);
}
/**
* Will cancel an in-progress connection, and close the socket
*/
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
}
}
}
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 = 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 {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI activity
//mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
// .sendToTarget();
processarMensagem(bytes);
Log.d(TAG, "received: " + bytes);
} 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);
Log.d(TAG, "sent: " + bytes);
} catch (IOException e) {
Log.e(TAG, e.getMessage(), e);
}
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
}
}
}
}
在多處發生IOException,然後默默丟棄它。這使得弄清楚哪裏出錯幾乎是不可能的。 –