Android之串口通信基础

Android之串口通信及指纹模块基础介绍

前段时间因项目性质原因开始接触人脸识别、指纹、身份证读取等方面,遇到了不少问题,其中在对接硬件方面的指纹模块时走了很多弯路,在此简单的介绍一下使用到的串口通讯知识,希望能对各位小伙伴有一定的帮助同时也是我自己的一个笔记,文章中如有错误、不当之处,还请指正。


串口通信

首先需要用到google官方提供的开源项目serialPort api ,下载地址为:serialPort api
1. 我们新建一个项目,将刚才下载的serialPort api 中的以下文件拷进我们项目中的对应文件夹
Android之串口通信基础_第1张图片

我们可以打开刚才拷贝到jni文件夹下的SerialPort.h,可以看到open和close两个方法定义的所在包名和类名
Android之串口通信基础_第2张图片
所以我们新建Package命名为android_serialport_api,同时将SerialPort.java文件拷贝至该文件夹下
Android之串口通信基础_第3张图片
2. 在module的build.grade中加入如下代码块
Android之串口通信基础_第4张图片

    sourceSets {
        main {
            jni.srcDirs = [] //禁止使用默认的ndk编译系统
            jniLibs.srcDirs 'libs' //so存放地方
        }
    }

3.我们打开SerialPort.java简单看一下里面的方法
Android之串口通信基础_第5张图片
我们就是用这两个方法来开启串口和关闭串口,因为是native方法,方法名报红,我们可以不用在意。

可以看到open开启串口这个方法需要两个参数,第一个参数是我们要开启的串口的绝对路径,第二个是对应的波特率。
4. 开启串口

    private FileDescriptor mFd;
    private FileInputStream mFileInputStream;
    private FileOutputStream mFileOutputStream;

    public SerialPort(File device, int baudrate) throws SecurityException, IOException {
        if (!device.canRead() || !device.canWrite()) {
            try {
                Process su;
                su = Runtime.getRuntime().exec("su");
                String cmd = "chmod 777 " + device.getAbsolutePath();
                su.getOutputStream().write(cmd.getBytes());
                su.getOutputStream().flush();
                int waitFor = su.waitFor();
                boolean canRead = device.canRead();
                boolean canWrite = device.canWrite();
                if (waitFor != 0 || !canRead || !canWrite) {
                    throw new SecurityException();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        mFd = open(device.getAbsolutePath(), baudrate);
        if (mFd == null) {
            Log.e(TAG, "串口开启失败,native open returns null");
            throw new IOException();
        }
        //Log.d(TAG,"串口开启成功");
        mFileInputStream = new FileInputStream(mFd);
        mFileOutputStream = new FileOutputStream(mFd);
    }

我们在构造方法传入了两个参数分别是我们要开启的串口和对应的波特率,调用open(device.getAbsolutePath(), baudrate)这个方法后我们获得了一个FileDescriptor对象,通过FileDescriptor我们可以获取到相应的FileInputStreamFileOutputStream,我们之后和硬件设备通信都是通过FileOutputStream向其发送指令,然后通过FileInputStream读取返回的数据信息。

5.该类的完整代码如下

public class SerialPort {
    private static final String TAG = "=====SerialPort";

    static {
        System.loadLibrary("serial_port");
    }

    private FileDescriptor mFd;
    private FileInputStream mFileInputStream;
    private FileOutputStream mFileOutputStream;

    public SerialPort(File device, int baudrate) throws SecurityException, IOException {
        if (!device.canRead() || !device.canWrite()) {
            try {
                Process su;
                su = Runtime.getRuntime().exec("su");
                String cmd = "chmod 777 " + device.getAbsolutePath();
                su.getOutputStream().write(cmd.getBytes());
                su.getOutputStream().flush();
                int waitFor = su.waitFor();
                boolean canRead = device.canRead();
                boolean canWrite = device.canWrite();
                if (waitFor != 0 || !canRead || !canWrite) {
                    throw new SecurityException();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        mFd = open(device.getAbsolutePath(), baudrate);
        if (mFd == null) {
            Log.e(TAG, "串口开启失败,native open returns null");
            throw new IOException();
        }
        //Log.d(TAG,"串口开启成功");
        mFileInputStream = new FileInputStream(mFd);
        mFileOutputStream = new FileOutputStream(mFd);
    }

    /**
     * JNI
     */
    private native static FileDescriptor open(String path, int baudrate);

    public native void close();

    /**
     * 关闭串口
     */
    public void closePort() {
        if (this.mFd != null) {
            try {
                this.close();
                this.mFd = null;
                this.mFileInputStream = null;
                this.mFileOutputStream = null;
                //Log.d(TAG,"串口关闭成功");
            } catch (Exception e) {
                Log.e(TAG,"关闭串口出现异常:"+e.toString());
            }
        }
    }

    public InputStream getInputStream() {
        return mFileInputStream;
    }

    public OutputStream getOutputStream() {
        return mFileOutputStream;
    }
}

demo下载地址:Android串口通信demo

你可能感兴趣的:(Android)