您的位置:首页 > 移动开发 > Android开发

android之蓝牙通信(二)(蓝牙连接,数据传递)

2016-11-25 10:35 531 查看
上次写了android之蓝牙通信(一)(基础之检测蓝牙、开启蓝牙、扫描附近蓝牙设备)

,大致介绍了开启蓝牙,搜索附近蓝牙设备功能,下面接下来写下搜索到蓝牙设备后进行连接,传递数据的操作,连接蓝牙设备有两种,一种是单向,一种是双向。单向是它发数据,你接受就行;双向是它发数据,你接收,你也发数据,它接收,双向的最佳例子就是蓝牙聊天。单向跟双向的做法差不多,单向只需要做个接收就行,而双向比单向多一个发送功能,具体的差异上一篇说过,双向是即作为服务器也作为客户端,单向是只需要作为客户端就行。

由于项目是做连接蓝牙秤获取蓝牙秤的数据,所以就以单向为例了,双向原理类似,多一个accept()和作为service服务器,具体就不多说了。

废话不多说了,直接上代码,首先,连接设备(很多人写的时候都是直接进行连接,没有先进行配对而是直接连接操作,这种方式不稳定,未配对的直接进行连接不稳定,有时候会很久连不上,所以先进行配对判断,配对过了直接连接,未配对的先进行配对,配对成功后再进行连接):

//配对连接线程
private class ClientThread extends Thread {
@Override
public void run() {
if (bluetoothAdapter.isDiscovering()) {
bluetoothAdapter.cancelDiscovery();
}

try {
if (device.getBondState() == BluetoothDevice.BOND_NONE) {  //未配对,就先配对,再连接
Method m = BluetoothDevice.class.getMethod("createBond");
m.invoke(device);
} else if (device.getBondState() == BluetoothDevice.BOND_BONDED) {  //已配对,直接连接
try {
MlogUtil.d(MlogUtil.MY_TEST, "开始连接");
socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
socket.connect();  //进行socket连接
Message succeedMsg = new Message();
succeedMsg.what = 1;
handler.sendMessage(succeedMsg);  //连接成功,发送消息给UI线程,进行提示
clientThread = null;
readThread = new ReadThread();  //连接成功后开启读取数据的线程
readThread.start();
} catch (IOException e) {
MlogUtil.d(MlogUtil.MY_TEST, "连接异常");
}
}
} catch (Exception e) {
MlogUtil.d(MlogUtil.MY_TEST, "配对异常");
}
}
}
连接设备和读取数据都需要新启线程在子线程中进行,因为过程比较耗时,如果不在子线程影响效率和阻塞UI。代码我就不做解释了,上面注释写的很清楚了。下面贴读取数据的操作:
//读写线程
private class ReadThread extends Thread {
@Override
public void run() {
byte[] buffer = new byte[1024];
int bytes;
InputStream mmInStream = null;   //建立输入流读取数据
try {
mmInStream = socket.getInputStream();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while (true) {  //无限循环读取数据
try {
// Read from the InputStream
if ((bytes = mmInStream.read(buffer)) > 0) {
byte[] buf_data = new byte[bytes];
for (int i = 0; i < bytes; i++) {
buf_data[i] = buffer[i];
}
String s = new String(buf_data);
final String data = MyUtil.getResult(s);
if (!TextUtils.isEmpty(data)) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Intent intent = new Intent(MyUtil.BOLOOTH_SEND_DATA);
intent.putExtra("data", data);
getActivity().sendBroadcast(intent);  //获取到蓝牙数据,传递数据
}
});
}
}
} catch (IOException e) {
handler.sendEmptyMessage(3);
try {
mmInStream.close();
} catch (IOException e1) {

}
break;  //异常的时候break跳出无限循环
}
}
}
}


上面是以流的形式读取数据。

还差一个,就是配对成功后进行连接,所以做个广播接收者,接收配对广播,成功后直接进行连接,广播接收者就不说了,自己脑补,比较简单。下面需要结束连接:

/* 停止客户端连接 */
private void shutdownClient() {
new Thread() {
@Override
public void run() {
if (socket != null) {
try {
socket.close();
socket = null;
} catch (IOException e) {
// TODO Auto-generated catch block
socket = null;
}
}
if (clientThread != null) {
clientThread.interrupt();
clientThread = null;
}
if (readThread != null) {
readThread.interrupt();
readThread = null;
}
}
}.start();
}


当连接失败时需要断开重连或者关闭当前页面时断开连接,执行下就可以了,还有些其他细节上的就不多说了,重点就是这几个操作,至于双向的还需要写个服务器和accept(),这个也不多说了,网上很多,也比较简单。

废话就不多说了,其实也不难,所以也不多做解释了,有什么问题也可以留言。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: