一直想花时间使用一下安卓的蓝牙,在学妹的激励下终于完成了这个心愿
这个app实现的功能是通过蓝牙连接单片机,在app中设置相应的四个参数发送,app可能通过特定的编码格式发送至下位机,同时后台接受下位机返回的数据,解码后显示在app的相应控件中。
代码在这:github这个用的是比较旧版本的sdk和eclipse,所以呢如果想要用的话就直接吧对应的类扒出来用吧,另外这一部分工作是统一上传的,所以和别的工程放在同一个repository里了,见谅
我觉得我这个界面特别好看,抄的是ingress的配色。后来做的一些软件,也都沿用了这个风格。
最底部的终端是调试用的,显示一些报错信息什么的,挺有用的,就留下来了。
蓝牙初始化连接,放在这个按钮监听器中,搜索制定名称的蓝牙设备:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
private class BtnConnectListener implements OnClickListener { @Override public void onClick(View v) { // 如果已经配对,直接返回 if (state) { Toast.makeText(getApplicationContext(), "设备已经连接了", Toast.LENGTH_SHORT).show(); return; } // 蓝牙的初始化 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); if (adapter != null) { textChat.setText(textChat.getText() + "设备拥有蓝牙\n"); if (!adapter.isEnabled()) { textChat.setText(textChat.getText() + "设备蓝牙未启动\n"); Intent intent = new Intent( BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivity(intent); textChat.setText(textChat.getText() + "设备蓝牙已由程序开启\n"); } else { textChat.setText(textChat.getText() + "设备蓝牙已启动\n"); } // 遍历配对的蓝牙设备 // Log.i("tag","222"); Set<BluetoothDevice> devices = adapter.getBondedDevices(); if (devices.size() > 0) { Boolean flag = false; // Log.i("tag","1"); for (Iterator iterator = devices.iterator(); iterator .hasNext();) { // Log.i("tag","2"); BluetoothDevice device = (BluetoothDevice) iterator .next(); textChat.setText(textChat.getText() + "发现设备" + device.getName() + "\n"); if (device.getName().equals(deviceName)) { try { bts = device .createRfcommSocketToServiceRecord(UUID .fromString(uuid)); bts.connect(); textChat.setText(textChat.getText() + "和单片机连接成功\n"); state = true; textDevice.setText(deviceName); textDevice.setTextColor(0xff1fded9); // 处理接收事务的handler handler = new Handler() { public void handleMessage(Message m) { if (m.what == 1) { textChat.setText(textChat.getText() + "她说:" + mess + "\n"); char[] chars = mess.toCharArray(); if(chars.length>=14){ if(chars[0]=='#'&&chars[13]=='!'){ realTem=(chars[1]-'0')*100+(chars[2]-'0')*10+(chars[3]-'0'); realHum=(chars[4]-'0')*100+(chars[5]-'0')*10+(chars[6]-'0'); realIrr=(chars[7]-'0')*100+(chars[8]-'0')*10+(chars[9]-'0'); realSmo=(chars[10]-'0')*100+(chars[11]-'0')*10+(chars[12]-'0'); textRealTem.setText("实际温度\n"+realTem); textRealHum.setText("实际湿度\n"+realHum); textRealIrr.setText("实际光照\n"+realIrr); textRealSmo.setText("烟雾浓度\n"+realSmo); Calendar calendar = Calendar.getInstance(); textRevTime.setText("最近数据接收时间\n" + (calendar.get(Calendar.MONTH) + 1) + "." + calendar.get(Calendar.DATE) + " " + calendar.get(Calendar.HOUR) + ":" + calendar.get(Calendar.MINUTE) + ":" + calendar.get(Calendar.SECOND)); } } } super.handleMessage(m); } }; new Thread(new ReadHandlerClientThread()) .start(); // Log.i("tag", "start"); } catch (IOException e) { // TODO Auto-generated catch block textChat.setText(textChat.getText() + "和单片机连接失败,重启一下单片机和这个程序吧\n"); } // Log.i("tag","true"); flag = true; break; } } if (flag == false) { textChat.setText(textChat.getText() + "配对设备里没有" + deviceName + "\n"); } } else { textChat.setText(textChat.getText() + "没有配对设备,请去系统蓝牙自行配对\n"); } } else { textChat.setText(textChat.getText() + "这只手机好像没有蓝牙\n"); } } } |
由于android中只允许主线程操控控件,而项目中需要使用多线程接收数据,
这里提供的解决方法是:
使用Handler这一个消息相应的类,在主线程中创建,副线程监听消息,即时同时handler处理事务
监听线程,监听同时筛选信息,讲需要传递的信息赋值给全局变量mess,通知handler去读取这个信息。
早期写的代码真的有点脏乱差。。后来我把蓝牙的使用封装在一个类里了,应该后期也会上传。