Android之串口编程

现在咱们生活中充满了各类智能设备,方便了咱们的生活,这正是物联网时代。若是咱们要开发智能设备,那么Android串口编程是咱们应该必备的技能。java


在投身到Android开发行业前,做者一直觉得Android开发就是单纯的写手机端应用。随着接触的项目愈来愈多,渐渐的开始接触到了Android应用结合控制硬件设备的项目了,应用控制锁、打印机、扫码器等等,这正是要使用到安卓串口编程的知识。android

STEP1

安卓串口编程中使用到的是谷歌开源serialPort api
git

下载连接:
github

github.com/cepr/androi…
编程

在GitHub上把所需资源下载下来以后就能够按下图的目录结构放置资源
api


请读者注意框框内的东东,其中应为使用到Google的原生so库,SerialPort类的包名必定要是android_serialport_api,若是想修改这个包名,就须要从新生成对应的so库。
数组


还有就是SerialPort.java文件中的open()close()方法虽然是红色的但咱们不用理会,编译是经过的。
安全

STEP2

在项目gradle文件中的buildTypes节点下加上下面一句话
bash


STEP3

编写封装串口工具类,主要分为如下步骤来打开串口:app

  1. 设置端口号、波特率

  2. 获取打开的串口中的输入输出流,以便于串口数据的收发

  3. 打开读取串口信息线程(接收串口返回信息不少时候都是须要等待的耗时操做,所以开启线程去等待)

  4. 绑定串口返回监听


path:端口号,必定要以这种格式编写,针对硬件的不一样可能会用到/dev/ttyS2或者/dev/ttyS1等等。

baudrate:波特率

serialPortStatus:串口打开标志

data_:发送的串口数据

threadStatus:终止线程标志位(这里更应该加上Volatile修饰)

mSerialPort:谷歌提供的api

mInputStream:串口输入流

mOutputStream:串口输出流

/**     * 打开串口     * @return  serialPort串口对象     */    public SerialPort openSerialPort(){        try{            mSerialPort = new SerialPort(new File(path), baudrate, 0);            this.serialPortStatus = true;            threadStatus = false;
            //获取打开的串口中的输入输出流,以便于串口数据的收发            mInputStream = mSerialPort.getInputStream();            mOutputStream = mSerialPort.getOutputStream();
            new ReadThread().start();//开启线程监控是否有数据的收发        }catch (IOException e){            Log.e(TAG, "openSerialPort:打开串口异常:" + e.toString());            return mSerialPort;        }        Log.d(TAG, "openSerialPort: 打开串口");        return mSerialPort;    }复制代码

打开串口方法主要完成了使用Google API的构造方法传入端口号和波特率,获取输入输出流,打开监听线程。

/**     * 关闭串口     */    public void closeSerialPort(){        try{            if (mInputStream != null){                mInputStream.close();            }            if (mOutputStream != null){                mOutputStream.close();            }            this.threadStatus = true;            this.serialPortStatus = false;            mSerialPort.close();        }catch (IOException e){            Log.e(TAG, "closeSerialPort: 关闭串口异常" + e.toString());            return;        }        Log.d(TAG, "closeSerialPort: 串口关闭成功");    }复制代码

关闭串口方法里主要完成了把输入输出流关闭,调用Google API关闭串口方法和使用标志位方法安全关闭监听线程。

public void sendSerialPort(String data){        Log.d(TAG, "sendSerialPort: 发送数据" + data);        try{            byte[] sendData = data.getBytes("gb2312");            this.data_ = new String(sendData);            if (sendData.length > 0){                mOutputStream.write(sendData);                mOutputStream.write('\n');                mOutputStream.flush();                Log.d(TAG, "sendSerialPort: 发送串口数据成功");            }        }catch (IOException e){            Log.e(TAG, "sendSerialPort: 串口发送数据失败 " + e.toString());        }    }复制代码

发送方法中,这个方法只是针对打印机操做实例来实现的,红框中咱们要把发送的字符串换成gb2312byte数组发送出去。

其实在串口通信中,全部的指令都要转化为byte数组发送出去的。你们能够在做者的这个简单工具类中加以改进,使其更加通用。

private class ReadThread extends Thread{        @Override        public void run() {            super.run();            //判断线程是否安全进行,更安全的结束线程            while (!threadStatus){                Log.d(TAG, "进入线程run");
                byte[] buffer = new byte[64];                int size;                try{                    size = mInputStream.read(buffer);                    if (size>0){                        Log.d(TAG, "run: 接收到数据大小:" + size);                        onDataReceiveListener.onDataReceive(buffer, size);                    }                }catch (IOException e){                    Log.e(TAG, "run: 数据读取异常" + e.toString());                }            }        }    }复制代码

监听线程中重点在try代码块中,InputStream.read()方法是一个阻塞操做,可根据项目须要使用interrupt()方法快速关闭线程,无需使用标志位等待到下一个循环才结束。

此外try代码块中还调用了onDataReceive()自定义接口的方法,用于返回线程监听的数据。

public OnDataReceiveListener onDataReceiveListener = null;
public static interface OnDataReceiveListener{        void onDataReceive(byte[] buffer, int size);    }
    public void setOnDataReceiveListener(OnDataReceiveListener listener){        this.onDataReceiveListener = listener;    }复制代码

工具类中还有一个OnDataReceiveListener变量,用于在外部调用者设置监听的接口。

注意这里onDataReceive()方法中的参数 buffer,一样的道理串口发送指令最终转换为byte数组发送,接收到的信息一样也是byte数组类型,因此根据需求能够将这个byte数组转化为字符串等等其余。

下面提供byte数组转换为字符串的方法和字符串转换成十六进制byte数组的方法。



完整代码:

github.com/YKamh/Seria…

PS:Demo只是简单实现了基本的串口编程功能,并无对细节优化。

结语

面临物联网时代的趋势,android串口编程也是咱们所应该必备的。在以上知识点中,其中的的核心代码依然是Java基础,也体现出Java基础的重要性。

在做者接触结合硬件的项目的时候,心情是仿佛发现了新大陆,串口编程更是有趣,没有开发纯应用的枯燥。

但愿你们一块儿努力,一块儿成长!

                                                          ----- End -----

                                                               更多好文

                                                        请扫描下面二维码

                                                              欢迎关注~