Android之串口编程

栏目: IOS · Android · 发布时间: 6年前

内容简介:阅读时长:10分钟原文地址:原文作者:YKamh

阅读时长:10分钟

原文地址: juejin.im/post/5bd96c…

原文作者:YKamh

技术预备:Java基础

如今我们生活中充满了各种智能设备,方便了我们的生活,这正是物联网时代。如果我们要开发智能设备,那么Android串口编程是我们应该必备的技能。

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

STEP1

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

下载链接:

github.com/cepr/androi…

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

Android之串口编程

请读者注意框框内的东东,其中应为使用到Google的原生so库,SerialPort类的包名一定要是android_serialport_api,如果想修改这个包名,就需要重新生成对应的so库。

Android之串口编程

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

STEP2

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

Android之串口编程

STEP3

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

  1. 设置端口号、波特率

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

  3. 打开读取串口信息线程(接收串口返回信息很多时候都是需要等待的耗时操作,因此开启线程去等待)

  4. 绑定串口返回监听

Android之串口编程
  • 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());
    }
}
复制代码

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

其实在串口通讯中,所有的指令都要转化为byte数组发送出去的。大家可以在作者的这个简单工具类中加以改进,使其更加通用。

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数组的方法。

Android之串口编程
Android之串口编程

完整代码:

github.com/YKamh/Seria…

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

结语

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

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

希望大家一起努力,一起成长!

----- End -----

更多好文

请扫描下面二维码

欢迎关注~

Android之串口编程

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

ppk谈JavaScript

ppk谈JavaScript

Peter-Paul Koch / 淘宝UED / 人民邮电出版社 / 2008-4 / 59.00元

本书全方位介绍了JavaScript,主要讨论了浏览器兼容性、可访问性、底层语法以及与HTML结构层的协同等问题。书中既包括理论性的讲解,又给出了相关的示例脚本以进行进一步阐述。通过8个真实项目示例,介绍了JavaScript核心语言、BOM、事件处理、DOM、修改CSS样式表以及数据检索等内容。 本书适合具有一定网页开发经验的Web开发人员阅读。一起来看看 《ppk谈JavaScript》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

URL 编码/解码
URL 编码/解码

URL 编码/解码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具