Android串口通信可以实现设备与设备之间通过设备线连接进行数据(消息)传递
(一)导入so库
Android 串口通信_第1张图片
(二)在moudle的build中添加jniLibs

buildTypes {             sourceSets {                 main {      jni.srcDirs = [] }        }    }

(三)添加Google的SerialPort
添加的是Google的所以必须创建android_serialport_api包
如需要更改SerialPort、SerialPortFinder位置需要重新生成so库
Android 串口通信_第2张图片

(四)创建串口通信工具类SerialPortUtils

package com.demo.serialport;import android.util.Log;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import android_serialport_api.SerialPort;/** * @author renquan */public class SerialPortUtils {         private final String TAG = "SerialPortUtils";//    private String path = "/dev/ttyS1";//    private int baudrate = 9600;    public boolean serialPortStatus = false; //是否打开串口标志    public String data_;    public boolean threadStatus; //线程状态,为了安全终止线程    public SerialPort serialPort = null;    public InputStream inputStream = null;    public OutputStream outputStream = null;    public ChangeTool changeTool = new ChangeTool();    /**     * 打开串口     * @return serialPort串口对象     */    public SerialPort openSerialPort(String path,int baudrate){             try {                 serialPort = new SerialPort(new File(path),baudrate,0);            this.serialPortStatus = true;            threadStatus = false; //线程状态            //获取打开的串口中的输入输出流,以便于串口数据的收发            inputStream = serialPort.getInputStream();            outputStream = serialPort.getOutputStream();            new ReadThread().start(); //开始线程监控是否有数据要接收        } catch (IOException e) {                 Log.e(TAG, "openSerialPort: 打开串口异常:" + e.toString());            return serialPort;        }        Log.d(TAG, "openSerialPort: 打开串口");        return serialPort;    }    /**     * 关闭串口     */    public void closeSerialPort(){             try {                 inputStream.close();            outputStream.close();            this.serialPortStatus = false;            this.threadStatus = true; //线程状态            serialPort.close();        } catch (IOException e) {                 Log.e(TAG, "closeSerialPort: 关闭串口异常:"+e.toString());            return;        }        Log.d(TAG, "closeSerialPort: 关闭串口成功");    }    /**     * 发送串口指令(字符串)     * @param data String数据指令     */    public void sendSerialPort(String data){             Log.d(TAG, "sendSerialPort: 发送数据");        try {                 byte[] sendData = data.getBytes(); //string转byte[]            this.data_ = new String(sendData); //byte[]转string            if (sendData.length > 0) {                     outputStream.write(sendData);                outputStream.write('\n');                //outputStream.write('\r'+'\n');                outputStream.flush();                Log.d(TAG, "sendSerialPort: 串口数据发送成功");            }        } catch (IOException e) {                 Log.e(TAG, "sendSerialPort: 串口数据发送失败:"+e.toString());        }    }    /**     * 单开一线程,来读数据     */    private class ReadThread extends Thread{             @Override        public void run() {                 super.run();            //判断进程是否在运行,更安全的结束进程            while (!threadStatus){                     Log.d(TAG, "进入线程run");                //64   1024                byte[] buffer = new byte[64];                int size; //读取数据的大小                try {                         size = inputStream.read(buffer);                    if (size > 0){                             Log.d(TAG, "run: 接收到了数据:" + changeTool.ByteArrToHex(buffer));                        Log.d(TAG, "run: 接收到了数据大小:" + String.valueOf(size));                        onDataReceiveListener.onDataReceive(buffer,size);                    }                } catch (IOException e) {                         Log.e(TAG, "run: 数据读取异常:" +e.toString());                }            }        }    }    //数据回调    public OnDataReceiveListener onDataReceiveListener = null;    public static interface OnDataReceiveListener {             public void onDataReceive(byte[] buffer, int size);    }    public void setOnDataReceiveListener(OnDataReceiveListener dataReceiveListener) {             onDataReceiveListener = dataReceiveListener;    }}
package com.demo.serialport;/** * @author renquan */public class ChangeTool {         /**     * byte数组转16进制字符串     *     * @param bytes byte数组     * @return 16进制字符串     */    public String ByteArrToHex(byte[] bytes) {             String strHex;        StringBuilder sb = new StringBuilder();        for (byte aByte : bytes) {                 strHex = Integer.toHexString(aByte & 0xFF);            sb.append(" ").append((strHex.length() == 1) ? "0" : "").append(strHex); // 每个字节由两个字符表示,位数不够,高位补0        }        return sb.toString().trim();    }    /**     * byte字节转int     *     * @param b byte字节     * @return int     */    public static int byteToInt(byte b) {             int x = b & 0xff;        if (x == 127) {                 return 0;        }        return x;    }}
package com.demo.serialport;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.EditText;import androidx.appcompat.app.AppCompatActivity;/** * @author renquan */public class MainActivity extends AppCompatActivity implements View.OnClickListener {         private EditText mMessage;    private Button mOpen;    private Button mSend;    private Button mClose;    private SerialPortUtils serialPortUtils;    @Override    protected void onCreate(Bundle savedInstanceState) {             super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        init();        //串口数据监听事件        serialPortUtils.setOnDataReceiveListener(new SerialPortUtils.OnDataReceiveListener() {                 @Override            public void onDataReceive(byte[] buffer, int size) {                     Log.d("TAG", "进入数据监听事件中。。。" + new String(buffer));            }        });    }    private void init() {             initView();        serialPortUtils = new SerialPortUtils();    }    private void initView() {             mMessage = (EditText) findViewById(R.id.message);        mOpen = (Button) findViewById(R.id.open);        mOpen.setOnClickListener(this);        mSend = (Button) findViewById(R.id.send);        mSend.setOnClickListener(this);        mClose = (Button) findViewById(R.id.close);        mClose.setOnClickListener(this);    }    @Override    public void onClick(View v) {             switch (v.getId()) {                 case R.id.open:                // TODO 20/12/28                serialPortUtils.openSerialPort("/dev/ttyS9",9600);                break;            case R.id.send:                // TODO 20/12/28                serialPortUtils.sendSerialPort(mSend.getText().toString());                break;            case R.id.close:                serialPortUtils.closeSerialPort();                // TODO 20/12/28                break;            default:                break;        }    }}

Demo——github地址

更多相关文章

  1. Android 多线程之 Handler 基本使用
  2. Android应用数据备份
  3. 【Android】数据存储之SQLite
  4. 如何查看无法导出的android数据库文件?
  5. Android本地数据存储之Sharedpreference
  6. Android线程池
  7. Android Java 线程池 ScheduledThreadPoolExecutor源码篇

随机推荐

  1. android中加载assets中的资源文件
  2. How the Dalvik Virtual Machine Works o
  3. android textview 自动连接网址及修改默
  4. 图+文+文显示
  5. 【Android】解析JSON数据详解
  6. Android 系统服务 - AMS 的启动过程
  7. Android中设定EditText的输入长度
  8. android lint 是什么
  9. android开发技巧精髓八
  10. 使用 kotlin 来进行 Android(安卓)开发(一