上一篇写了我把官方的结构给改了,下面就直接上各个线程分开的代码了!
Java
public class AcceptThread extends Thread { private Handler mHandler; private ConnectedThread mConnectedThread; private String TAG = "AcceptThread"; private boolean D = true; private String NAME = "Service"; private BluetoothAdapter adpter; private final BluetoothServerSocket mmServerSocket; public AcceptThread(Handler handler) { adpter = BluetoothAdapter.getDefaultAdapter(); mHandler = handler; BluetoothServerSocket tmp = null; try { tmp = adpter.listenUsingRfcommWithServiceRecord(NAME, Constant.MY_UUID); // Method mthd = adpter.getClass().getMethod("listenUsingRfcommOn", // new Class[] { int.class }); // tmp = (BluetoothServerSocket) mthd.invoke(adpter, // new Object[] { 29 }); } catch (Exception e) { Log.e(TAG, "listen() failed", e); } mmServerSocket = tmp; System.out.println("+++++" + mmServerSocket); } @Override public void run() { // TODO Auto-generated method stub super.run(); if (D) Log.d(TAG, "BEGIN mAcceptThread" + this); setName("AcceptThread"); BluetoothSocket socket = null; try { socket = mmServerSocket.accept(); System.out.println("socket---" + socket); } catch (Exception e) { Log.e(TAG, "accept() failed", e); } if (socket != null) { connected(socket, socket.getRemoteDevice()); try { mmServerSocket.close(); } catch (Exception e) { Log.e(TAG, "Could not close unwanted socket", e); } } if (D) Log.i(TAG, "END mAcceptThread"); } public void cancel() { if (D) Log.d(TAG, "cancel " + this); try { mmServerSocket.close(); } catch (Exception e) { Log.e(TAG, "close() of server failed", e); } } public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) { if (D) Log.d(TAG, "connected"); mConnectedThread = new ConnectedThread(mHandler, socket); mConnectedThread.start(); Constant.setConnectedThread(mConnectedThread); Message msg = mHandler.obtainMessage(Constant.MESSAGE_DEVICE_NAME); Bundle bundle = new Bundle(); bundle.putString(Constant.DEVICE_NAME, device.getName()); msg.setData(bundle); mHandler.sendMessage(msg); } }
上面这些代码是AcceptThread类,这个类主要是用来接收蓝牙连接请求,注释掉的几句是我在网上看到的,说是在系统版本比较高的时候就换成了那种方式进行连接的,我试了试,虽然请求方显示的是连接成功了,但是接收方却没什么反应,不知道是不是因为我测试的都是两个手机不是都是较高版本的原因,总之就先没用那种方式,以后有机会可以测试一下是否可用。
接下来贴上主动请求连接的线程的代码。
Java
public class ConnectThread extends Thread { private boolean D = true; private Handler mHandler; private ConnectedThread mConnectedThread; private BluetoothAdapter adapter; private String TAG = "ConnectThread"; private final BluetoothSocket mmSocket; private final BluetoothDevice mmDevice; private String failmesage; public ConnectThread(Handler handler, BluetoothDevice device) { mConnectedThread=Constant.getConnectedThread(); mHandler = handler; mmDevice = device; BluetoothSocket tmp = null; try { // Method method = device.getClass() // .getMethod("createRfcommSocket", // new Class[] { int.class }); // tmp = (BluetoothSocket) method.invoke(device, // new Object[] { 29 }); tmp = device.createRfcommSocketToServiceRecord(Constant.MY_UUID); } catch (Exception e) { Log.e(TAG, "create() failed", e); } mmSocket = tmp; } public void run() { Log.i(TAG, "BEGIN mConnectThread"); setName("ConnectThread"); adapter = BluetoothAdapter.getDefaultAdapter(); adapter.cancelDiscovery(); try { mmSocket.connect(); } catch (Exception e) { failmesage = "无法连接到设备"; connectionFailed(); try { mmSocket.close(); } catch (Exception e2) { Log.e(TAG, "unable to close() socket during connection failure", e2); } return; } connected(mmSocket, mmDevice); } public void cancel() { try { mmSocket.close(); } catch (Exception e) { Log.e(TAG, "close() of connect socket failed", e); } } private void connectionFailed() { Log.i(TAG, "conncet fail"); Message msg = mHandler.obtainMessage(Constant.MESSAGE_TOAST); Bundle bundle = new Bundle(); bundle.putString(Constant.TOAST, failmesage); msg.setData(bundle); mHandler.sendMessage(msg); } public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) { if (D) Log.d(TAG, "connected"); // Start the thread to manage the connection and perform transmissions mConnectedThread = new ConnectedThread(mHandler, socket); mConnectedThread.start(); Constant.setConnectedThread(mConnectedThread); // Send the name of the connected device back to the UI Activity Message msg = mHandler.obtainMessage(Constant.MESSAGE_DEVICE_NAME); Bundle bundle = new Bundle(); bundle.putString(Constant.DEVICE_NAME, device.getName()); msg.setData(bundle); mHandler.sendMessage(msg); } }
这个就是主动请求连接的线程,主要是用来实现请求连接那边已经等待连接的Socket,这很像网络里那种服务器端和客户端的概念,一个用来请求连接,一个用来接受连接。可以看到,无论是请求连接还是接受连接,它们在连接之前是一个线程,在连接之后这个线程就被终结了,而启动了另外一个线程,这个线程就是专门用来处理连接之后进行通信的线程,我把它命名为ConnectedThread,同时需要注意的是,
Constant.setConnectedThread(mConnectedThread);
这段代码是我将实例化之后的ConnectedThread对象存进了Constant这个类中,主要也是为了程序调用方面,也算是用到了单例模式,需要用到这个对象时候只需要在Constant类里面通过GetConnectedThread方法就可以获得。
下面是ConncetedThread类的源码部分
Java
public class ConnectedThread extends Thread { private Handler mHandler; private String TAG = "ConnectedThread"; private final BluetoothSocket mmSocket; private final InputStream mmInStream; private final OutputStream mmOutStream; public ConnectedThread(Handler handler, BluetoothSocket socket) { Log.d(TAG, "create ConnectedThread"); mHandler = handler; mmSocket = socket; InputStream tmpIn = null; OutputStream tmpOut = null; // Get the BluetoothSocket input and output streams try { tmpIn = socket.getInputStream(); tmpOut = socket.getOutputStream(); } catch (Exception e) { Log.e(TAG, "temp sockets not created", e); } mmInStream = tmpIn; mmOutStream = tmpOut; } public void run() { Log.i(TAG, "BEGIN mConnectedThread"); byte[] buffer = new byte[1024]; int bytes; while (true) { try { bytes = mmInStream.read(buffer); mHandler.obtainMessage(Constant.MESSAGE_READ, bytes, -1, buffer) .sendToTarget(); } catch (Exception e) { Log.e(TAG, "disconnected", e); connectionLost(); break; } } } public void write(byte[] buffer) { try { mmOutStream.write(buffer); } catch (Exception e) { Log.e(TAG, "Exception during write", e); } } public void cancel() { try { mmSocket.close(); } catch (Exception e) { Log.e(TAG, "close() of connect socket failed", e); } } private void connectionLost() { Log.i(TAG, "connect lost"); Constant.setConnectedThread(null); Message msg = mHandler.obtainMessage(Constant.MESSAGE_TOAST); Bundle bundle = new Bundle(); bundle.putString(Constant.TOAST, "设备连接已断开"); msg.setData(bundle); mHandler.sendMessage(msg); } }
这个就是用来处理连接之后进行通信的线程,用到了IO流对数据进行操作,要发送就调用write()方法,要接收就调用read()方法即可。它会向UI界面发送一个Message用来更新UI,下一篇附上UI接受的代码。
苏公网安备 32132202001088号
| Copyright 北极熊 北格技术 版权所有