安卓蓝牙通信
1.布局
基于前期的wechat中的tab01.xml进行添加,使其拥有对话框的控件。添加的代码如下:
<!--新版Android支持的Toolbar,对标题栏布局-->
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/title_left_text"
style="?android:attr/windowTitleStyle"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_weight="1"
android:gravity="left"
android:ellipsize="end"
android:singleLine="true" />
<TextView
android:id="@+id/title_right_text"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_weight="1"
android:ellipsize="end"
android:gravity="right"
android:singleLine="true"
android:textColor="#fff" />
</LinearLayout>
</android.support.v7.widget.Toolbar>
2.蓝牙通信的具体实现
这里需要用到UUID,UUID:通用唯一识别码,是一个128位长的数字,一般用十六进制表示,它主要是通过结合机器的网卡、当地时间、一个随机数来生成,不会重复。还需要用到蓝牙的基本类BluetoothAdapter类。
(1)书写构造方法,接收UI主线程传递的对象
public ChatService(Context context, Handler handler) {
//构造方法完成蓝牙对象的创建
mAdapter = BluetoothAdapter.getDefaultAdapter();
mState = STATE_NONE;
mHandler = handler;
}
(2)使用多线程,取消 CONNECTING 和 CONNECTED 状态下的相关线程,然后运行新的 mConnectThread 线程
public synchronized void connect(BluetoothDevice device) {
if (mState == STATE_CONNECTING) {
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
}
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
mConnectThread = new ConnectThread(device);
mConnectThread.start();
setState(STATE_CONNECTING);
}
(3)管理蓝牙的连接,使用socket套接字
public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
if (mAcceptThread != null) {
mAcceptThread.cancel();
mAcceptThread = null;
}
mConnectedThread = new ConnectedThread(socket);
mConnectedThread.start();
Message msg = mHandler.obtainMessage(weixinFragment.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(weixinFragment.DEVICE_NAME, device.getName());
msg.setData(bundle);
mHandler.sendMessage(msg);
setState(STATE_CONNECTED);
}
(4)对连接状态发生改变进行处理
连接失败的时候和当连接失去的时候,通知 ui,设置STATE_LISTEN 状态
private void connectionLost() {
setState(STATE_LISTEN);
Message msg = mHandler.obtainMessage(weixinFragment.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(weixinFragment.TOAST, "设备链接中断");
msg.setData(bundle);
mHandler.sendMessage(msg);
}
3.通信实现的思路
首先在构造函数里通过BluetoothDevice
.createRfcommSocketToServiceRecord() ,从待连接的 device 产生 BluetoothSocket. 然后在 run 方法中 connect ,成功后调用 BluetoothChatSevice 的 connected() 方法。定义 cancel() 在关闭线程时能够关闭相关socket ,对外发出连接对方蓝牙的请求。双方蓝牙连接后,构造函数中设置输入输出流。run()方法中使用阻塞模式的 InputStream.read()循环读取输入流,然后发送到 UI 线程中更新聊天消息。大概的思路就是这样。主要是能熟练运用线程和socket套接字。