android蓝牙和网络通信项目总结(一)
2015-09-02 18:27
603 查看
android蓝牙和网络通信项目总结(一)
最近在家没网络,用手机开热点做了一个蓝牙和网络通信的小项目,在这里总结一下。主要是和硬件通信的一个app啦,从同学那里拿个蓝牙模块做的测试,觉得挺有趣的,整个项目做下来,因为感觉有很多东西需要总结的,所以分几篇进行总结。一,扫描二维码
这个app的其中一个功能是扫描二维码,然后获得设备信息,添加设备,这样以后app就可以直接连接设备了,对于二维码的操作,我使用的是比较出名的zxing框架。在github上很容易找到可以使用的例子。首先我是先和做硬件的同学商量好怎么定二维码信息的格式的,商量好就好说了,打开myeclipse,写个生成二维码的工具,然后生成二维码。然后使用手机扫描二维码,获得数据,保存到手机。主要代码如下:Intent intent = new Intent(); intent.putExtra("result", rawResult.getText()); setResult(RESULT_OK, intent); rw = rawResult.getText().split("&@"); SmartDevice smartDevice = new SmartDevice(); smartDevice.setName(rw[0]); smartDevice.setPassword(rw[1]); smartDevice.setPath(rw[2]); for (int i = 3; i < rw.length-1; i+=2) { SmartOrder order = new SmartOrder(); order.setSmartOrder(rw[i]); order.setSmartRespense(rw[i+1]); order.save(); smartDevice.getSmartOrders().add(order); } smartDevice.save(); Intent i = new Intent(Config.notif2adddevice); i.putExtra("result", rawResult.getText()); mLocalBroadcastManager.sendBroadcast(i); finish();
smartdevice就是要保存的设备的类,包括名字,密码,发送的指令,响应的指令,设备蓝牙物理地址等,这是根据信息特定的排列存入的,以避免随便扫一个二维码就加一个设备。在最后发送一个broadcast,通知上一个activity添加设备,然后退出扫描,设备添加成功。
mLocalBroadcastManager = LocalBroadcastManager.getInstance(getActivity()); mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(Config.notif2adddevice)) { int drawable = 0; SmartDevice smartDevice = DataSupport.findLast(SmartDevice.class, true); devices.add(smartDevice); if (smartDevice.getName().contains("灯")) { drawable = R.drawable.light_on; } else if (smartDevice.getName().contains("门")) { drawable = R.drawable.door_on; } else if (smartDevice.getName().contains("路由器")) { drawable = R.drawable.luyouqi_on; } else { drawable = R.drawable.switch_on; } smartDevice.setDrawable(drawable); smartDevice.update(DataSupport.count(SmartDevice.class)); datas.add(datas.size() - 1, new CellData(smartDevice.getName(), drawable)); adapter.notifyDataSetChanged(); } } }; mLocalBroadcastManager.registerReceiver(mReceiver, filter);
上面是接受broadcast的主要代码,我主要想在所有设备的最后加一个添加设备的按钮,所以每次添加设备都添加在倒数第二个,最后一个是添加按钮。
二,关于读取信息
关于读取信息是挺麻烦的事情,上次下载的例子是使用thread的,但是要实现异步,还是用asynctask。还要区分蓝牙连接,和网络连接,开始想到的一个方法是,分别写一个读取,到时后来发现要很多冗余的代码,所以把他写成一个,主要代码如下:public class ReadMesThread extends AsyncTask { private InputStream mmInStream; int bytes; boolean isReading = true; public ReadMesThread(InputStream mmInStream){ this.mmInStream = mmInStream; } @Override protected Object doInBackground(Object[] objects) { while (!isCancelled()) { byte[] buffer = new byte[256]; if (mmInStream != null) { try { bytes = mmInStream.read(buffer); String readStr = new String(buffer, 0, bytes); String str = bytes2HexString(buffer).replaceAll("00", "").trim(); Log.i("result", str); } catch (IOException e) { e.printStackTrace(); Log.i("result", "standbyfail"); return null; } } } return null; } private String bytes2HexString(byte[] b) { String ret = ""; for (int i = 0; i < b.length; i++) { String hex = Integer.toHexString(b[i] & 0xFF); if (hex.length() == 1) { hex = '0' + hex; } ret += hex.toUpperCase(); } return ret; } }
一个线程控制两个信息读取,非常方便。在最后的一个方法是将字节转换成字符用的,因为发送到设备的数据必须是十六进制的,所以必须要转换。但上面的代码其实是不够严谨的,为什么呢?假设现在是使用网络连接,读到的数据有可能会出现StringIndexOutOfBoundsException这个异常,这里必须捕捉,并处理异常,代码要改成这样:
try { bytes = mmInStream.read(buffer); String readStr = new String(buffer, 0, bytes); String str = bytes2HexString(buffer).replaceAll("00", "").trim(); Log.i("result", str); } catch (IOException e) { handler.obtainMessage(Config.TIMEOUT).sendToTarget(); e.printStackTrace(); Log.i("result", "standbyfail"); return null; }catch (StringIndexOutOfBoundsException siob){ handler.obtainMessage(Config.SIOOBE).sendToTarget(); }使用handler在线程之间的通信,处理异常。
在读取信息的过程中,我还遇到一个很常见的错误,就是在一个activity中要是有一个执行长时操作的asynctask,activity被销毁的时候,那个asynctask是不会被销毁的,以至于下次再打开那个activity的时候,所有asynctask都跑不起来了,asyntask的生命周期被改变了,所以activity退出的时候一定要cancel掉asyntask,并且置空,例如:
if(connectThread!=null) { connectThread.cancel(true); connectThread = null; }
这种错误编译器是不报错的,非常隐秘,所以要切记!
三,总结
这次的项目是自己一个完成的,感觉挺累的,不过也充满了乐趣,学到很多东西啊项目的demo(不全)地址: 点击打开链接
相关文章推荐
- Android提高第二十篇之MediaPlayer播放网络音频
- Http请求头整理
- TCP重新发送
- httpClient服务端编写
- Apt-cacher-ng 配置Linux代理网络
- 使用golang做http接口压力测试并输出到echarts散点图中
- Android(java)学习笔记204:自定义SmartImageView(继承自ImageView,扩展功能为自动获取网络路径图片)
- Could not transfer artifact *************** from/to central (http://repo1.maven.org/maven2
- The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar
- 利用volley进行http设置请求头、超时及请求参数设置(post)
- 新博客(Hexo)地址:http://leoios.github.io
- 移动网络测试
- 使用Jstl异常:HTTP Status 500 - The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in
- Linux无法连接网络解决方案
- 定位http请求失败的问题。
- Volley网络框架学习笔记(四)
- 网络请求工具 SWIFT JSON解析
- 网络排错大讲解
- HTTP协议简介1
- ios https请求