Android适配安卓6.0蓝牙通讯实现过程
事先说明:
安卓蓝牙需要定位权限申请,在安卓6.0需要用户手动确认权限后才能使用,各位可以自行查询资料实现,如果嫌麻烦,可以用第三方bmob集成好的工具类进行实现,详细可以看http://blog.csdn.net/qq_30379689/article/details/52223244
蓝牙连接过程:
1、查询用户是否开启蓝牙。
2、搜索附近的可用的蓝牙。
3、进行蓝牙配对。
4、进行蓝牙连接。
5、获取输入流和输出流。
6、发送消息。
晒上我自己画的美图:
实验效果图:
实现需要的权限:由于安卓4.x以上的版本使用蓝牙,需要开启定位权限才能搜索到附近的蓝牙设备
<uses-permission android:name="android.permission.bluetooth"/> <uses-permission android:name="android.permission.bluetooth_admin"/> <uses-permission android:name="android.permission.access_fine_location" /> <uses-permission android:name="android.permission.access_coarse_location" />
服务端
实现思路:
1、拿到本地蓝牙设备。
2、蓝牙之间的通讯需要一个唯一识别uuid来匹配正确的设备,使用uuid获取蓝牙的通讯socket。
3、开启获取数据的线程
public class mainactivity extends appcompatactivity implements view.onclicklistener { bluetoothsocket btsocket; bluetoothadapter btadapter; button bt_start; textview tv_msg; stringbuilder sb; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); bt_start = (button) findviewbyid(r.id.bt_start); tv_msg = (textview) findviewbyid(r.id.tv_msg); bt_start.setonclicklistener(this); sb = new stringbuilder(); //拿到本地蓝牙设备 btadapter = bluetoothadapter.getdefaultadapter(); } /** * ui文本输出 * * @param msg */ public void show(string msg) { sb.append(msg + "\n"); runonuithread(new runnable() { @override public void run() { tv_msg.settext(sb.tostring()); } }); } @override public void onclick(view v) { //开启服务器 serverthread startserverthread = new serverthread(); startserverthread.start(); } /** * 开启服务器 */ private class serverthread extends thread { public void run() { try { bluetoothserversocket mserversocket = btadapter.listenusingrfcommwithservicerecord("btspp", uuid.fromstring("00001101-0000-1000-8000-00805f9b34fb")); show("服务端:等待连接"); btsocket = mserversocket.accept(); show("服务端:连接成功"); readthread mreadthread = new readthread(); mreadthread.start(); show("服务端:启动接受数据"); } catch (ioexception e) { e.printstacktrace(); } } } /** * 读取数据 */ private class readthread extends thread { public void run() { byte[] buffer = new byte[1024]; int bytes; inputstream mminstream = null; try { mminstream = btsocket.getinputstream(); show("服务端:获得输入流"); } catch (ioexception e1) { e1.printstacktrace(); } while (true) { try { 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); show("服务端:读取数据了~~" + s); } } catch (ioexception e) { try { mminstream.close(); } catch (ioexception e1) { e1.printstacktrace(); } break; } } } } }
客户端
实现思路:
1、检查是否开启蓝牙。
2、注册一系列蓝牙的广播。
3、由于蓝牙每经过一个阶段都会发送一个广播,根据广播来实现对应的方法。
4、蓝牙配对->蓝牙连接->发送消息(uuid必须相同)
public class mainactivity extends appcompatactivity implements view.onclicklistener { private textview tv_msg; private button bt_search, bt_send; private bluetoothsocket btsocket; private bluetoothadapter btadapter; private bluetoothdevice device; private stringbuilder sb; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); bt_search = (button) findviewbyid(r.id.bt_search); bt_send = (button) findviewbyid(r.id.bt_send); tv_msg = (textview) findviewbyid(r.id.tv_msg); bt_search.setonclicklistener(this); bt_send.setonclicklistener(this); sb = new stringbuilder(); show("客户端:检查bt"); checkbt(this); show("客户端:注册接收者"); registerbtreceiver(); } /** * ui文本输出 * * @param msg */ public void show(string msg) { sb.append(msg + "\n"); runonuithread(new runnable() { @override public void run() { tv_msg.settext(sb.tostring()); } }); } @override public void onclick(view v) { switch (v.getid()) { case r.id.bt_search: show("客户端:开始寻找设备"); btadapter.startdiscovery(); break; case r.id.bt_send: sendmessage(); break; } } /** * 检查蓝牙 */ public void checkbt(context context) { btadapter = bluetoothadapter.getdefaultadapter(); if (btadapter != null) { if (!btadapter.isenabled()) { intent intent = new intent(bluetoothadapter.action_request_enable); // 设置蓝牙可见性,最多300秒 intent.putextra(bluetoothadapter.extra_discoverable_duration, 300); context.startactivity(intent); } } else { system.out.println("本地设备驱动异常!"); } } /** * 开启客户端 */ private class clientthread extends thread { public void run() { try { //创建一个socket连接:只需要服务器在注册时的uuid号 btsocket = device.createrfcommsockettoservicerecord(uuid.fromstring("00001101-0000-1000-8000-00805f9b34fb")); //连接 show("客户端:开始连接..."); btsocket.connect(); show("客户端:连接成功"); //启动接受数据 show("客户端:启动接受数据"); readthread mreadthread = new readthread(); mreadthread.start(); } catch (ioexception e) { show("客户端:连接服务端异常!断开连接重新试一试"); e.printstacktrace(); } } } /** * 读取数据 */ private class readthread extends thread { public void run() { byte[] buffer = new byte[1024]; int bytes; inputstream is = null; try { is = btsocket.getinputstream(); show("客户端:获得输入流"); } catch (ioexception e1) { e1.printstacktrace(); } while (true) { try { if ((bytes = is.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); show("客户端:读取数据了" + s); } } catch (ioexception e) { try { is.close(); } catch (ioexception e1) { e1.printstacktrace(); } break; } } } } /** * 发送数据 */ public void sendmessage() { if (btsocket == null) { toast.maketext(this, "没有连接", toast.length_short).show(); return; } try { outputstream os = btsocket.getoutputstream(); os.write("我爱你dahsid132456@#%¥*".getbytes()); os.flush(); show("客户端:发送信息成功"); } catch (ioexception e) { e.printstacktrace(); } } /** * 注册广播 */ public void registerbtreceiver() { // 设置广播信息过滤 intentfilter intentfilter = new intentfilter(); intentfilter.addaction(bluetoothdevice.action_found); intentfilter.addaction(bluetoothadapter.action_discovery_started); intentfilter.addaction(bluetoothadapter.action_discovery_finished); intentfilter.addaction(bluetoothadapter.action_state_changed); intentfilter.addaction(bluetoothdevice.action_bond_state_changed); // 注册广播接收器,接收并处理搜索结果 registerreceiver(btreceive, intentfilter); } /** * 注销广播 */ public void unregisterbtreceiver() { unregisterreceiver(btreceive); } @override protected void ondestroy() { super.ondestroy(); unregisterbtreceiver(); } /** * 广播接收者 */ private broadcastreceiver btreceive = new broadcastreceiver() { @override public void onreceive(context context, intent intent) { string action = intent.getaction(); if (bluetoothdevice.action_found.equals(action)) { device = intent.getparcelableextra(bluetoothdevice.extra_device); show("客户端:找到的bt名:" + device.getname()); // 如果查找到的设备符合要连接的设备,处理 if (device.getname().equalsignorecase("xu")) { show("客户端:配对xu蓝牙:"); // 搜索蓝牙设备的过程占用资源比较多,一旦找到需要连接的设备后需要及时关闭搜索 btadapter.canceldiscovery(); // 获取蓝牙设备的连接状态 int connectstate = device.getbondstate(); switch (connectstate) { // 未配对 case bluetoothdevice.bond_none: show("客户端:开始配对:"); try { method createbondmethod = bluetoothdevice.class.getmethod("createbond"); createbondmethod.invoke(device); } catch (exception e) { e.printstacktrace(); } break; // 已配对 case bluetoothdevice.bond_bonded: try { show("客户端:开始连接:"); clientthread clientconnectthread = new clientthread(); clientconnectthread.start(); } catch (exception e) { e.printstacktrace(); } break; } } } else if (bluetoothdevice.action_bond_state_changed.equals(action)) { // 获取蓝牙设备的连接状态 int connectstate = device.getbondstate(); // 已配对 if (connectstate == bluetoothdevice.bond_bonded) { try { show("客户端:开始连接:"); clientthread clientconnectthread = new clientthread(); clientconnectthread.start(); } catch (exception e) { e.printstacktrace(); } } } show(action); } }; }
蓝牙广播内容:
action_state_changed 当你蓝牙开启或者关闭的时候发送
action_found 当你匹配到附近蓝牙设备时发送
action_discovery_started 当你开始搜索附近蓝牙设备时发送
action_discovery_finished 当你结束搜索附近蓝牙设备时发送
action_bond_state_changed 当你蓝牙设备匹配状态发生变化时发送
源码下载:http://xiazai.jb51.net/201609/yuanma/androidrobot(jb51.net).rar
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。