新年第一篇。
最近在做蓝牙开锁的小项目,手机去连接单片机总是出现问题,和手机的连接也不稳定,看了不少蓝牙方面的文档,做了个关于蓝牙连接的小结。
在做android蓝牙串口连接的时候一般会使用
[java] view plaincopyprint?
1 BluetoothSocket tmp = null;
2 // Get a BluetoothSocket for a connection with the
3 // given BluetoothDevice
4 try {
5 tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
6 } catch (IOException e) {
7 Log.e(TAG, "create() failed", e);
8 }
然后是tmp赋给BluetoothSocket,接着调用connect方法进行蓝牙设备的连接。
可是 BluetoothSocket 的connect方法本身就会报很多异常错误。
以下根据对蓝牙开发的一点研究可通过以下方法解决:
方法1.先进行蓝牙自动配对,配对成功,通过UUID获得BluetoothSocket,然后执行connect()方法。
方法2.通过UUID获得BluetoothSocket,然后先根据mDevice.getBondState()进行判断是否需要配对,最后执行connnect()方法。
[java] view plaincopyprint?
9 private class ConnectThread extends Thread {
10 String macAddress = "";
11
12 public ConnectThread(String mac) {
13 macAddress = mac;
14 }
15
16 public void run() {
17 connecting = true;
18 connected = false;
19 if(mBluetoothAdapter == null){
20 mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
21 }
22 mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(macAddress);
23 mBluetoothAdapter.cancelDiscovery();
24 try {
25 socket = mBluetoothDevice.createRfcommSocketToServiceRecord(uuid);
26
27 } catch (IOException e) {
28 // TODO Auto-generated catch block
29 //e.printStackTrace();
30 Log.e(TAG, "Socket", e);
31 }
32 //adapter.cancelDiscovery();
33 while (!connected && connetTime <= 10) {
34 connectDevice();
35 }
36 // 重置ConnectThread
37 //synchronized (BluetoothService.this) {
38 //ConnectThread = null;
39 //}
40 }
41
42 public void cancel() {
43 try {
44 socket.close();
45 socket = null;
46 } catch (Exception e) {
47 e.printStackTrace();
48 } finally {
49 connecting = false;
50 }
51 }
52 }
接下来是调用的连接设备方法connectDevice():
[java] view plaincopyprint?
53 protected void connectDevice() {
54 try {
55 // 连接建立之前的先配对
56 if (mBluetoothDevice.getBondState() == BluetoothDevice.BOND_NONE) {
57 Method creMethod = BluetoothDevice.class
58 .getMethod("createBond");
59 Log.e("TAG", "开始配对");
60 creMethod.invoke(mBluetoothDevice);
61 } else {
62 }
63 } catch (Exception e) {
64 // TODO: handle exception
65 //DisplayMessage("无法配对!");
66 e.printStackTrace();
67 }
68 mBluetoothAdapter.cancelDiscovery();
69 try {
70 socket.connect();
71 //DisplayMessage("连接成功!");
72 //connetTime++;
73 connected = true;
74 } catch (IOException e) {
75 // TODO: handle exception
76 //DisplayMessage("连接失败!");
77 connetTime++;
78 connected = false;
79 try {
80 socket.close();
81 socket = null;
82 } catch (IOException e2) {
83 // TODO: handle exception
84 Log.e(TAG, "Cannot close connection when connection failed");
85 }
86 } finally {
87 connecting = false;
88 }
89 }
方法3.利用反射通过端口获得BluetoothSocket,然后执行connect()方法。
[java] view plaincopyprint?
90 private class ConnectThread extends Thread {
91 String macAddress = "";
92
93 public ConnectThread(String mac) {
94 macAddress = mac;
95 }
96
97 public void run() {
98 connecting = true;
99 connected = false;
100 if(mBluetoothAdapter == null){
101 mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
102 }
103 mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(macAddress);
104 mBluetoothAdapter.cancelDiscovery();
105 initSocket();
106 //adapter.cancelDiscovery();
107 while (!connected && connetTime <= 10) {
108 try {
109 socket.connect();
110 connected = true;
111 } catch (IOException e1) {
112 connetTime++;
113 connected = false;
114 // 关闭 socket
115 try {
116 socket.close();
117 socket = null;
118 } catch (IOException e2) {
119 //TODO: handle exception
120 Log.e(TAG, "Socket", e2);
121 }
122 } finally {
123 connecting = false;
124 }
125 //connectDevice();
126 }
127 // 重置ConnectThread
128 //synchronized (BluetoothService.this) {
129 //ConnectThread = null;
130 //}
131 }
132
133 public void cancel() {
134 try {
135 socket.close();
136 socket = null;
137 } catch (Exception e) {
138 e.printStackTrace();
139 } finally {
140 connecting = false;
141 }
142 }
143 }
接下来是初始化并得到BluetoothSocket的方法
[java] view plaincopyprint?
144 /**
145 * 取得BluetoothSocket
146 */
147 private void initSocket() {
148 BluetoothSocket temp = null;
149 try {
150 Method m = mBluetoothDevice.getClass().getMethod(
151 "createRfcommSocket", new Class[] { int.class });
152 temp = (BluetoothSocket) m.invoke(mBluetoothDevice, 1);//这里端口为1
153 } catch (SecurityException e) {
154 e.printStackTrace();
155 } catch (NoSuchMethodException e) {
156 e.printStackTrace();
157 } catch (IllegalArgumentException e) {
158 e.printStackTrace();
159 } catch (IllegalAccessException e) {
160 e.printStackTrace();
161 } catch (InvocationTargetException e) {
162 e.printStackTrace();
163 }
164 socket = temp;
165 }
要点:1.蓝牙配对和连接是两回事,不可混为一谈。
2.蓝牙串口连接可通过端口 (1-30)和UUID两种方法进行操作。
3.通过UUID进行蓝牙连接最好先进行配对操作。