Android蓝牙开发经验总结(二)

 本来要昨天写的,但是昨天一忙倒是把写博客这件事给忘了,继续上一篇的写。

上一篇写了我把官方的结构给改了,下面就直接上各个线程分开的代码了!

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类,这个类主要是用来接收蓝牙连接请求,注释掉的几句是我在网上看到的,说是在系统版本比较高的时候就换成了那种方式进行连接的,我试了试,虽然请求方显示的是连接成功了,但是接收方却没什么反应,不知道是不是因为我测试的都是两个手机不是都是较高版本的原因,总之就先没用那种方式,以后有机会可以测试一下是否可用。

接下来贴上主动请求连接的线程的代码。

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类的源码部分

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接受的代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值