Android(安卓)之 串口通信
16lz
2021-01-24
阅读前提:串口通信是单片机采用RS232与Android板进行通信,首先要了解RS232发送数据的工作原理:RS232发送数据的时候是通过一个字节接着一个字节,将数据发送出去,所以当接收数据时候也应当一个字节一个字节接受
在AndroidManifest.xml中加入权限
/*允许程序对SD卡进行写入*/<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>/*允许程序对SD卡进行读取*/<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
1.登陆GitHub下载android-serialport-api
下载地址:GitHub-android-serialport-api
①首先,在main的文件夹中新建一个叫android_serialport_api的文件夹,并且把android_serialport_api中的中的SerialPort中的文件复制到文件夹
②新建一个jni和jniLibs的文件夹,把android_serialport_api对应的文件复制过来
2.建立SerialPortUtil单例模式
这里简单介绍:
详细请看:StormZhang的Android设计模式之单例模式
单例模式:单例模式就是保证你全局有且只有这个类的一个实例,这个实例可以在全局使用,并且这个实例会为全局提供访问的节点
全局的概念:全局在这里可以理解为整一个Application,这个类在整个Application中永远只会被实例化一次(即new),当JVM检测到这个实例不再使用就会被垃圾回收机制回收了,那么当代码运行到需要这个实例的时候,发现这个实例不存在就会把这个类再实例化一次,这样就保证了内存中只有一个类的实例而不是多个实例
为什么类只实例化一个:这里涉及到一个内存的使用的问题,如果一个类被实例化了多次,在内存中就会占有多个同一个类的多个实例,这样就浪费内存,减慢代码运行效率。只使用一个实例可以节省内存,提高代码的运行效率。
在我这里使用的是一个叫懒汉模式的单例模式
public class SerialPortUtil { //这个就是需要被实例化的类 private static SerialPortUtil INSTANCE = null; //这里必须需要一个私有的构造器 private SerialPortUtil(){ } //这里为全局提供访问的节点 public static SerialPortUtil getInstance(){ //涉及延时加载,当需要这个类的时候才会被实例化 if (INSTANCE == null){ INSTANCE = new SerialPortUtil(); } return INSTANCE; }}
当对串口进行数据的通信时候,进行四个步骤:①打开串口、②发送数据、③接受数据、④关闭串口
//打开串口 private void openSerialPort(){ try { /*设置打开的串口*/ final String portPath = "/dev/ttyS0"; /*设置波特率*/ final int baudRate = 115200; serialPort = new SerialPort(new File(portPath),baudRate,0); outputStream = serialPort.getOutputStream(); inputStream = serialPort.getInputStream(); /*开启线程读取数据*/ new ReadThread().start(); }catch (IOException e){ e.printStackTrace(); } } //关闭串口 private void closeSerialPort(){ try{ inputStream.close(); outputStream.close(); serialPort.close(); }catch (IOException e){ e.printStackTrace(); } } //发送数据 private void sendDataToSerialPort(byte[] data){ try{ int dataLength = data.length; Log.d("DATASIZE",String.valueOf(dataLength)); if(dataLength > 0){ outputStream.write(data); outputStream.write('\n'); outputStream.flush(); } }catch (IOException e){ e.printStackTrace(); } } //接收数据的线程 private class ReadThread extends Thread { @Override public void run() { super.run(); while(!isInterrupted()) { int size; try { byte[] buffer = new byte[64]; if (inputStream == null) return; size = inputStream.read(buffer); if (size > 0) { SCMDataReceiveListener.dataRecevie(buffer, size);//监听数据的传输 } } catch (IOException e) { e.printStackTrace(); return; } } } }
接收数据通过接口进行接收数据
//设置监听接口 public void setSCMDataReceiveListener(SCMDataReceiveListener SCMDataReceiveListener) { this.SCMDataReceiveListener = SCMDataReceiveListener; }
3.SerialPortUtil源码
public class SerialPortUtil { private static SerialPortUtil INSTANCE = null; private SerialPort serialPort; private OutputStream outputStream; private InputStream inputStream; private SCMDataReceiveListener SCMDataReceiveListener; private SerialPortUtil(){ } public static SerialPortUtil getInstance(){ if (INSTANCE == null){ INSTANCE = new SerialPortUtil(); } return INSTANCE; } public void setSCMDataReceiveListener(SCMDataReceiveListener SCMDataReceiveListener) { this.SCMDataReceiveListener = SCMDataReceiveListener; } private void openSerialPort(){ try { final String portPath = "/dev/ttyS0"; final int baudRate = 115200; serialPort = new SerialPort(new File(portPath),baudRate,0); outputStream = serialPort.getOutputStream(); inputStream = serialPort.getInputStream(); new ReadThread().start(); }catch (IOException e){ e.printStackTrace(); } } public void closeSerialPort(){ try{ inputStream.close(); outputStream.close(); serialPort.close(); }catch (IOException e){ e.printStackTrace(); } } private void sendDataToSerialPort(byte[] data){ try{ int dataLength = data.length; Log.d("DATASIZE",String.valueOf(dataLength)); if(dataLength > 0){ outputStream.write(data); outputStream.write('\n'); outputStream.flush(); } }catch (IOException e){ e.printStackTrace(); } } private class ReadThread extends Thread { @Override public void run() { super.run(); while(!isInterrupted()) { int size; try { byte[] buffer = new byte[1]; if (inputStream == null) return; size = inputStream.read(buffer); if (size > 0) { /*监听数据接收*/ SCMDataReceiveListener.dataRecevie(buffer, size); } } catch (IOException e) { e.printStackTrace(); return; } } } }}
4.设置串口监听回调接口
public interface SCMDataReceiveListener { void dataRecevie(byte[] data,int size);}
更多相关文章
- Android图灵机器人的实现(一)
- 三分钟搞定Android数据库升级
- Android数据持久化之文件存储
- Android--GreenDao
- android 识别U盘以及读写文件的方法
- Android四大组之ContentProvider
- 更快实现Android多级树形选择列表
- Android上传图片的方式
- Android最新组件RecyclerView,替代ListView