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后赋值给我们真正要使用的变量。这种做法的好处就是:如果我们直接就是使用真正的变量,当出现异常的时候,该变量的使用就会出现问题,而且很难进行排查,如果是临时变量,我么可以通过检查变量的值来确定是否是赋值时出错。

   

手机与单片机通过蓝牙通信----手机控制灯

环境   1、普中科技HC6800-EM3 v2.2 单片机开发实验仪(芯片STC90C516RD+)           2、无线蓝牙串口透传模块 HC-06从机           3、windo...
  • itas109
  • itas109
  • 2013年05月18日 16:54
  • 6758

安卓手机通过蓝牙与单片机通信

概述:            手机端打开编写的蓝牙通信软件,与单片机端蓝牙串口模块连接,而后,手机通过蓝牙发送读数据命令到单片机,单片机开始读取传感器信息,将采集到得传感器信息通过蓝牙发送到手机端,...
  • gaixm
  • gaixm
  • 2014年04月10日 15:47
  • 4239

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

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

安卓手机通过蓝牙与单片机通信

概述:            手机端打开编写的蓝牙通信软件,与单片机端蓝牙串口模块连接,而后,手机通过蓝牙发送读数据命令到单片机,单片机开始读取传感器信息, 将采集到得传感器信息通过蓝牙发送到手机...
  • czthisme123
  • czthisme123
  • 2014年10月30日 23:29
  • 1857

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

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

实现蓝牙HC-05、06与单片机的连接及与手机通信(转)

蓝牙(Bluetooth):是一种无线技术标准,可实现固定设备、移动设备和楼宇个人域网之间的短距离数据交换(使用2.4—2.485GHz的ISM波段的UHF无线电波)。蓝牙技术最初由电信巨头爱立信公司...
  • wuermohuang
  • wuermohuang
  • 2016年05月22日 13:38
  • 11430

关于socket通讯阻塞以及java与单片机通讯问题详解

本公司是生产智能水表的,有个工程是集中器与后台服务器socket通讯。接到这个任务时,一脸懵逼,因为以前是做安卓的,从来没写过socket通讯,期间,遇到了无数的问题,翻阅了无数资料,经过十几个夜晚的...
  • u012210347
  • u012210347
  • 2016年08月18日 16:37
  • 474

单片机中的几种通信方式

首先弄懂串行通信和并行通信以及串口通信和并口通信的概念。 串行通行:它是一个概念,它是指数据一位一位地顺序传送,其特点就是通信线路 简单,只要一对传输线就可实现双向通信,适用于远距离通信,但传输速度慢...
  • qq_36629451
  • qq_36629451
  • 2017年07月24日 23:06
  • 887

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

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

单片机控制串口通信

串口通信的内容比较重要,大家一定要掌握,工业上应用非常多,其中232总线、485总线以及以它们为基础建成的ModBus网络工业通信系统都需要用到串口,下面我来为大家一步步介绍串口通信的相关知识。 ...
  • snyanglq
  • snyanglq
  • 2015年12月17日 17:04
  • 1247
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:android开发之手机与单片机蓝牙模块通信
举报原因:
原因补充:

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