【android 串口开发(二) 之 串口读写操作】
16lz
2021-01-23
串口的读写操作
看这篇文章前,建议先看看这篇文章: 【android 串口开发(一) 之生成so文件】
既然,我们的so已经生成了,那么接下来就是串口的读写操作啦。
下面贴出关键类的代码:
** * 串口操作类 */public class SerialPortUtil { private String TAG = SerialPortUtil.class.getSimpleName(); private SerialPort mSerialPort; private OutputStream mOutputStream; private InputStream mInputStream; private ReadThread mReadThread; private String path = "/dev/ttyS4"; //这个是我们要读取的串口路径,这个硬件开发人员会告诉我们的 private int baudrate = 9600;//这个参数,硬件开发人员也会告诉我们的 private static SerialPortUtil portUtil; private OnDataReceiveListener onDataReceiveListener = null; private boolean isStop = false; public interface OnDataReceiveListener { public void onDataReceive(byte[] buffer, int size); } public void setOnDataReceiveListener(OnDataReceiveListener dataReceiveListener) { onDataReceiveListener = dataReceiveListener; } public static SerialPortUtil getInstance() { if (null == portUtil) { portUtil = new SerialPortUtil(); portUtil.onCreate(); } return portUtil; } /** * 初始化串口信息 */ public void onCreate() { try { mSerialPort = new SerialPort(new File(path), baudrate, 0); mOutputStream = mSerialPort.getOutputStream(); mInputStream = mSerialPort.getInputStream(); mReadThread = new ReadThread(); isStop = false; mReadThread.start(); } catch (Exception e) { e.printStackTrace(); } } /** * 发送指令到串口 * * @param cmd * @return */ public boolean sendCmds(String cmd) { boolean result = true; String str = cmd; str = str.replace(" ", ""); byte[] mBuffer = SerialDataUtils.HexToByteArr(str); if (!isStop) { try { if (mOutputStream != null) { mOutputStream.write(mBuffer); } else { result = false; } } catch (IOException e) { e.printStackTrace(); result = false; } } else { System.out.println("sendCmds serialPort isClose"); result = false; } return result; } private class ReadThread extends Thread { @Override public void run() { super.run(); System.out.println("ReadThread.run isInterrupted()=" + isInterrupted()); while (!isStop && !isInterrupted()) { System.out.println("ReadThread.run mInputStream=" + mInputStream); int size; try { if (mInputStream == null){ System.out.println("ReadThread.run return"); return; } byte[] buffer = new byte[512]; System.out.println("ReadThread.run buffer"); size = mInputStream.read(buffer);//该方法读不到数据时,会阻塞在这里 System.out.println("ReadThread.run size=" + size); if (size > 0) { /* if(MyLog.isDyeLevel()){ MyLog.log(TAG, MyLog.DYE_LOG_LEVEL, "length is:"+size+",data is:"+new String(buffer, 0, size)); }*/ byte[] buffer2 = new byte[size]; for (int i = 0; i < size; i++) { buffer2[i] = buffer[i]; } if (onDataReceiveListener != null) { onDataReceiveListener.onDataReceive(buffer2, size); } } Thread.sleep(50);//延时 50 毫秒 } catch (Exception e) { e.printStackTrace(); System.out.println("ReadThread.run e.printStackTrace() " + e); return; } } } } /** * 关闭串口 */ public void closeSerialPort() { isStop = true; if (mReadThread != null) { mReadThread.interrupt(); } if (mSerialPort != null) { mSerialPort.close(); } }}
把这个进制转换的工具类也贴出一下:
package com.everyoo.serialportdaemon2;/** * 串口数据转换工具类 * Created by Administrator on 2016/6/2. */public class SerialDataUtils { //------------------------------------------------------- // 判断奇数或偶数,位运算,最后一位是1则为奇数,为0是偶数 public static int isOdd(int num) { return num & 1; } //------------------------------------------------------- //Hex字符串转int public static int HexToInt(String inHex) { return Integer.parseInt(inHex, 16); } //------------------------------------------------------- //Hex字符串转byte public static byte HexToByte(String inHex) { return (byte) Integer.parseInt(inHex, 16); } //------------------------------------------------------- //1字节转2个Hex字符 public static String Byte2Hex(Byte inByte) { return String.format("%02x", new Object[]{inByte}).toUpperCase(); } //------------------------------------------------------- //字节数组转转hex字符串 public static String ByteArrToHex(byte[] inBytArr) { StringBuilder strBuilder = new StringBuilder(); for (byte valueOf : inBytArr) { strBuilder.append(Byte2Hex(Byte.valueOf(valueOf))); strBuilder.append(" "); } return strBuilder.toString(); } //------------------------------------------------------- //字节数组转转hex字符串,可选长度 public static String ByteArrToHex(byte[] inBytArr, int offset, int byteCount) { StringBuilder strBuilder = new StringBuilder(); int j = byteCount; for (int i = offset; i < j; i++) { strBuilder.append(Byte2Hex(Byte.valueOf(inBytArr[i]))); } return strBuilder.toString(); } //------------------------------------------------------- //转hex字符串转字节数组 public static byte[] HexToByteArr(String inHex) { byte[] result; int hexlen = inHex.length(); if (isOdd(hexlen) == 1) { hexlen++; result = new byte[(hexlen / 2)]; inHex = "0" + inHex; } else { result = new byte[(hexlen / 2)]; } int j = 0; for (int i = 0; i < hexlen; i += 2) { result[j] = HexToByte(inHex.substring(i, i + 2)); j++; } return result; }}
最后你在你的MainActivity中,直接调用 serialPort.sendCmds(“7e01010d”) 方法即可,需要注意一点的就是:像7e01010d 是十六进制的字符:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.inject(this); initEvent(); SerialPortUtil serialPort = SerialPortUtil.getInstance(); //该方法是读取数据的回调监听,一旦读取到数据,就立马回调 serialPort.setOnDataReceiveListener(new SerialPortUtil.OnDataReceiveListener() { @Override public void onDataReceive(byte[] buffer, int size) { receiveString = SerialDataUtils.ByteArrToHex(buffer).trim(); System.out.println("MainActivity2.onDataReceive receiveString= " + receiveString); runOnUiThread(new Runnable() { @Override public void run() { result.append(receiveString + "\r\n"); } }); } }); }
CMake相关参考文章:
Android开发:JNI开发过程以及两种生成.so文件的方法
Android Studio中CMakeList的写法
Android-串口(通过jni技术生成自己的so)
google官方地址: https://github.com/cepr/android-serialport-api
android串口通信以及串口协议解析
android 串口编程
Android串口通信:串口读写实例
【Android应用开发】-(19)Android 串口编程原理和实现方式(附源码)
更多相关文章
- Android串口通信实例分析【附源码】
- Android - 字符串的加密和解密
- android设置字符串到剪贴板
- Android 取得对话框中EditText的字符串
- android 项目串口通信(serialPort)开发遇到的炕
- android工程字符串多语言翻译遗漏查找工具
- android中流的理解。(字节流读写与字符流的读写)