android开发之手机与单片机蓝牙模块通信

转载 2015年10月22日 09:40:52

之前两篇都是在说与手机的连接,连接方法,和主动配对连接,都是手机与手机的操作,做起来还是没问题的,但是最终的目的是与单片机的蓝牙模块的通信。

 

下面是到目前为止尝试的与单片机的通信方法,没有成功,但是从思路上来说没有问题,最大的问题是与单片机配对的时候,单片机的蓝牙模块的PIN配对码是写死的,固定为1234,

而手机这边连接配对都是自动生成的PIN配对码,这种方式在手机与手机配对的时候是极为方便的,但是在这里与单片机连接却成了最大的问题,因为手机自动生成而且每次都不一样,所以没法与单片机蓝牙模块的1234相同也就没法陪对了。下面只是介绍的到目前为止我们的大题思路,具体代码很多,而且涉及到项目也就没有贴。

如果关于上面的问题哪位同学有思路或者做过类似的项目还请指点。

 

首先,如何开启蓝牙设备和设置可见时间:

[java] view plaincopyprint?

private void search() {  

        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();  

        if (!adapter.isEnabled()) {  

            adapter.enable();  

        }  

        Intent enable = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);  

        enable.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 3600); //3600为蓝牙设备可见时间  

         startActivity(enable);  

        Intent searchIntent = new Intent(this, ComminuteActivity.class);  

10         startActivity(searchIntent);  

11     }  


正式开始与蓝牙模块进行通信

[java] view plaincopyprint?

12 public class ComminuteActivity extends Activity {  

13     private BluetoothReceiver receiver;  

14     private BluetoothAdapter bluetoothAdapter;  

15     private List<String> devices;  

16     private List<BluetoothDevice> deviceList;  

17     private Bluetooth client;  

18     private final String lockName = "YESYOU";  

19     private String message = "000001";  

20     private ListView listView;  

21   

22     @Override  

23     public void onCreate(Bundle savedInstanceState) {  

24         super.onCreate(savedInstanceState);  

25         setContentView(R.layout.search_layout);  

26   

27         listView = (ListView) this.findViewById(R.id.list);  

28         deviceList = new ArrayList<BluetoothDevice>();  

29         devices = new ArrayList<String>();  

30         bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();  

31         bluetoothAdapter.startDiscovery();  

32         IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);  

33         receiver = new BluetoothReceiver();  

34         registerReceiver(receiver, filter);  

35   

36         listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {  

37             @Override  

38             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {  

39                 setContentView(R.layout.connect_layout);  

40                 BluetoothDevice device = deviceList.get(position);  

41                 client = new Bluetooth(device, handler);  

42                 try {  

43                     client.connect(message);  

44                 } catch (Exception e) {  

45                     Log.e("TAG", e.toString());  

46                 }  

47             }  

48         });  

49     }  

50   

51     @Override  

52     protected void onDestroy() {  

53         unregisterReceiver(receiver);  

54         super.onDestroy();  

55     }  

56   

57     private final Handler handler = new Handler() {  

58         @Override  

59         public void handleMessage(Message msg) {  

60             switch (msg.what) {  

61                 case Bluetooth.CONNECT_FAILED:  

62                     Toast.makeText(ComminuteActivity.this, "连接失败", Toast.LENGTH_LONG).show();  

63                     try {  

64                         client.connect(message);  

65                     } catch (Exception e) {  

66                         Log.e("TAG", e.toString());  

67                     }  

68                     break;  

69                 case Bluetooth.CONNECT_SUCCESS:  

70                     Toast.makeText(ComminuteActivity.this, "连接成功", Toast.LENGTH_LONG).show();  

71                     break;  

72                 case Bluetooth.READ_FAILED:  

73                     Toast.makeText(ComminuteActivity.this, "读取失败", Toast.LENGTH_LONG).show();  

74                     break;  

75                 case Bluetooth.WRITE_FAILED:  

76                     Toast.makeText(ComminuteActivity.this, "写入失败", Toast.LENGTH_LONG).show();  

77                     break;  

78                 case Bluetooth.DATA:  

79                     Toast.makeText(ComminuteActivity.this, msg.arg1 + "", Toast.LENGTH_LONG).show();  

80                     break;  

81             }  

82         }  

83     };  

84   

85     private class BluetoothReceiver extends BroadcastReceiver {  

86         @Override  

87         public void onReceive(Context context, Intent intent) {  

88             String action = intent.getAction();  

89             if (BluetoothDevice.ACTION_FOUND.equals(action)) {  

90                 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);  

91                 if (isLock(device)) {  

92                     devices.add(device.getName());  

93                 }  

94                 deviceList.add(device);  

95             }  

96             showDevices();  

97         }  

98     }  

99   

100     private boolean isLock(BluetoothDevice device) {  

101         boolean isLockName = (device.getName()).equals(lockName);  

102         boolean isSingleDevice = devices.indexOf(device.getName()) == -1;  

103         return isLockName && isSingleDevice;  

104     }  

105   

106     private void showDevices() {  

107         ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,  

108                 devices);  

109         listView.setAdapter(adapter);  

110     }  

111 }  

这里需要提一下的是,startDiscovery()这个方法和它的返回值,它是一个异步方法,会对其他蓝牙设备进行搜索,持续时间为12秒。

搜索过程其实是在System Service中进行,我们可以通过cancelDiscovery()方法来停止这个搜索。在系统搜索蓝牙设备的过程中,系统可能会发送以下三个广播:ACTION_DISCOVERY_START(开始搜索),

ACTION_DISCOVERY_FINISHED(搜索结束)

和ACTION_FOUND(找到设备)。

ACTION_FOUND这个才是我们想要的,这个Intent中包含两个extra fields:    EXTRA_DEVICE和EXTRA_CLASS,

包含的分别是BluetoothDevice和BluetoothClass,

EXTRA_DEVICE中的BluetoothDevice就是我们搜索到的设备对象,从中获得设备的名称和地址。

而EXTRA_CLASS中的BluetoothClass是搜索到的设备的类型,比如搜索到的是手机还是耳机或者其他,之后我会写一篇关于它的介绍。

在这个上面我现在在想,是否通过判断搜索到的设备类型来识别单片机蓝牙模块与手机蓝牙的不同,采取不一样的配对方式,从而不自动生成配对码。不知是否可行,一会尝试。

 

 搜索到该设备后,我们就要对该设备进行连接和通信。

[java] view plaincopyprint?

112 public void connect(final String message) {  

113         Thread thread = new Thread(new Runnable() {  

114             public void run() {  

115                 BluetoothSocket tmp = null;  

116                 Method method;  

117                 try {  

118                     method = device.getClass().getMethod("createRfcommSocket", new Class[]{int.class});  

119                     tmp = (BluetoothSocket) method.invoke(device, 1);  

120                 } catch (Exception e) {  

121                     setState(CONNECT_FAILED);  

122                     Log.e("TAG", e.toString());  

123                 }  

124                 socket = tmp;  

125                 try {  

126                     socket.connect();  

127                     isConnect = true;  

128                 } catch (Exception e) {  

129                     setState(CONNECT_FAILED);  

130                     Log.e("TAG", e.toString());  

131                 }  

132            if (isConnect) {  

133                     try {  

134                         OutputStream outStream = socket.getOutputStream();  

135                         outStream.write(getHexBytes(message));  

136                     } catch (IOException e) {  

137                         setState(WRITE_FAILED);  

138                         Log.e("TAG", e.toString());  

139                     }  

140                     try {  

141                         InputStream inputStream = socket.getInputStream();  

142                         int data;  

143                         while (true) {  

144                             try {  

145                                 data = inputStream.read();  

146                                 Message msg = handler.obtainMessage();  

147                                 msg.what = DATA;  

148                                 msg.arg1 = data;  

149                                 handler.sendMessage(msg);  

150                             } catch (IOException e) {  

151                                 setState(READ_FAILED);  

152                                 Log.e("TAG", e.toString());  

153                                 break;  

154                             }  

155                         }  

156                     } catch (IOException e) {  

157                         setState(WRITE_FAILED);  

158                         Log.e("TAG", e.toString());  

159                     }  

160                 }  

161   

162                 if (socket != null) {  

163                     try {  

164                         socket.close();  

165                     } catch (IOException e) {  

166                         Log.e("TAG", e.toString());  

167                     }  

168                }  

169        }  

170 }  

 这里包括写入和读取,用法和基本的Socket是一样的,但是写入的时候,需要将字符串转化为16进制:

[java] view plaincopyprint?

171 private byte[] getHexBytes(String message) {  

172         int len = message.length() / 2;  

173         char[] chars = message.toCharArray();  

174         String[] hexStr = new String[len];  

175         byte[] bytes = new byte[len];  

176         for (int i = 0, j = 0; j < len; i += 2, j++) {  

177             hexStr[j] = "" + chars[i] + chars[i + 1];  

178             bytes[j] = (byte) Integer.parseInt(hexStr[j], 16);  

179         }  

180         return bytes;  

181     }  

 


  

连接设备之前需要UUID,所谓的UUID,就是用来进行配对的,全称是Universally Unique Identifier,是一个128位的字符串ID,用于进行唯一标识。网上的例子,包括谷歌的例子提供的uuid,通用的"00001101-0000-1000-8000-00805F9B34FB"也试过了,在配对的时候都是自动生成了配对码,也无法正常与单片机的蓝牙模块连接,所以,我就利用反射的原理,让设备自己提供UUID尝试。到这里其实我有点怀疑自己对于UUID的理解是否正确了。

            在谷歌提供的例子中,我们可以看到谷歌的程序员的程序水平很高,一些好的编码习惯我们可以学习一下,像是在try..catch中才定义的变量,我们应该在try...catch之前声明一个临时变量,然后再在try...catch后赋值给我们真正要使用的变量。这种做法的好处就是:如果我们直接就是使用真正的变量,当出现异常的时候,该变量的使用就会出现问题,而且很难进行排查,如果是临时变量,我么可以通过检查变量的值来确定是否是赋值时出错。

   

相关文章推荐

android开发之蓝牙配对连接的方法

新年第一篇。最近在做蓝牙开锁的小项目,手机去连接单片机总是出现问题,和手机的连接也不稳定,看了不少蓝牙方面的文档,做了个关于蓝牙连接的小结。 在做android蓝牙串口连接的时候一般会使用 Bluet...

关于Android蓝牙串口通信那点破事

Android蓝牙串口通讯 闲着无聊玩起了Android蓝牙模块与单片机蓝牙模块的通信,简单思路就是要手机通过蓝牙发送控制指令给单片机,并作简单的控制应用。单片机的蓝牙模块连接与程序暂且略过,此文主...

Android之蓝牙 一个简单实用的Android蓝牙程序实例

作者:   张奇        我将在这篇文章中介绍了的Android蓝牙程序。这个程序就是将实现把手机变做电脑PPT播放的遥控器:用音量加和音量减键来控制PPT页面的切换。 遥控器服务器...
  • lqhed
  • lqhed
  • 2016年09月20日 11:20
  • 731

android开发之手机与单片机蓝牙模块通信

本文转载自:http://blog.csdn.net/jason0539/article/details/17880071、 http://blog.csdn.net/jason0539之前两篇都是...

android开发之手机与单片机蓝牙模块通信

之前两篇都是在说与手机的连接,连接方法,和主动配对连接,都是手机与手机的操作,做起来还是没问题的,但是最终的目的是与单片机的蓝牙模块的通信。   下面是到目前为止尝试的与单片机的通信方法,没有成功,但...

【Android开发 蓝牙通信】手机蓝牙与下位机HC-05蓝牙模块通信系统

【周记-Android移动端开发】手机蓝牙与下位机HC-05蓝牙模块通信系统 很久没有写博客了,计划一直都有,但总是被这样或者那样的事情给耽搁了,在此写下文字监督自己:不论长短,每周至少一篇!本文...

Android开发之蓝牙(二)——基于BLE协议蓝牙模块通信

介绍 基本概念 Android蓝牙开发流程 app是ble与spp选择连接蓝牙模块,关于spp的可以看 介绍摘要:蓝牙4.0——BLE是近年来应用比较广泛的profile,与传统蓝牙相比,其低功耗的...

Android手机蓝牙与单片机蓝牙串通信开发经验总结

最近辛辛苦苦的终于把落下了七八个月的Android蓝牙开发搞完了,其中的痛苦不堪回首啊。感谢那些帮了大忙的老师和同学们!辛苦归辛苦,收获总是有的,因而在此总结一下关键所在,以勉励自己!        ...

android 手机与单片机之间的蓝牙通信

刚好碰到这蓝牙通信方面的项目,上网也看过其他人在蓝牙这方面写的博客,但大多都不全,给一些初触蓝牙的开发者造成一定的麻烦,自己当初也费了不少劲。所以把自己参考网上的一些资料用Android studio...

Android手机蓝牙与单片机通信数据格式问题

1.单片机发的是ASCII码,手机这边收的是
  • SBADHWM
  • SBADHWM
  • 2014年11月13日 09:27
  • 2179
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:android开发之手机与单片机蓝牙模块通信
举报原因:
原因补充:

(最多只允许输入30个字)