准备材料

AndroidStudio

谷歌android-serialport-api

前情提要

网上提供很多基于c语言对安卓串口开发,有jni、cmake等等,不过都太高深,谷歌提供的api已经可以满足基本读写(对数据位、停止位、校验位无要求,默认N81),这也是最简单的串口开发。

Java并不是直接调用c中的函数去和串口交互,而是用cmake或jni编译c得到的so库文件实现的,所以使用谷歌api不用再去把他的c文件之类的拿来,只用把他的so库文件拿来用即可,也不用知道so文件怎么用,谷歌demo中写好了直接调用so文件的java类,所以最终我们只需要导入需要的东西然后在谷歌串口类之上编写就行了。

开始骚操作

  1. 首先解压谷歌api demo放一边备用;
  2. 新建AS项目,一路next,拿到一个空空的自带界面的项目;
  3. 打开项目目录app下的build.gradle,在buildTypes同级设置so文件的lib位置,这里用的自己生成的libs文件夹
android {

    compileSdkVersion 28

    defaultConfig {

        applicationId "com.example.hp.demo"

        minSdkVersion 19

        targetSdkVersion 28

        versionCode 1

        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

    }

    buildTypes {

        release {

            minifyEnabled false

            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

        }

    }

    sourceSets.main{

        jniLibs.srcDirs = ['libs']

    }

}

  

  1. 打开谷歌api对应的lib文件夹android-serialport-api\android-serialport-api\project\libs,将里面的三种CPU架构用的so文件夹全复制过去
  2. 打开谷歌api的源代码目录android-serialport-api\android-serialport-api\project\src,内含谷歌api串口开发地基,将该文件夹android_serialport_api直接复制到自己项目java文件夹内(和com同级)
  3. android_serialport_api这个文件夹包含三件物品:

sample:谷歌api DEMO所用演示代码,移植到自己项目后直接删除,不然会和xml接不上报错

SerialPort.java:我们直接接触的对串口开发操作的类,串口读写都基于此,由该文件和so文件对接,我们的操作和该文件对接

SerialPortFinder.java:一般用不到(我没用到),可以找到并输出所有可用串口名和路径,可能是用于对串口批量操作的,一两个串口的用不到

  1. 在此再次说一下:正常大神操作是,先写c文件和h文件,然后jni或cmake编译得出so文件,然后写调用so文件的java类,然后再调用该java类进行各种操作;

我们的操作是上述操作的最后一步,直接用谷歌大佬写好的c编译好的so写好的java类,在这之上写我们自己的操作

  1. 这时就已经可以准备自己的操作了,在此之前检查几个地方:

1)第3点是否写好

2)SerialPort.java中的末尾有这么一段代码:

static {

System.loadLibrary("serial_port");

}

  

这就是传说中调用so库的地方,第三点没写好是找不到这个库的,此外(“”)中的库名也要和so文件对应,即so文件的libserial_port.so去掉开头lib就是库名

  1. 我们的骚操作刚刚开始:

1) 写一个基于SerialPort.java封装好的串口类,虽然已经可以直接用SerialPort.java,但是SerialPort.java中的方法还是稍微有点基层,当项目里有对多个串口进行不同的操作时这一步是必要的,不然代码太重复繁琐,封装的串口类应该有这几个功能:

从外部设置串口号、波特率

向外部传递串口返回报文

打开串口,获取输入输出流

关闭串口,关闭输入输出流

向串口写入字节*

向串口写入字节数组*

向串口写入字符串*

实时监听串口,获取完整的报文

具体代码见Demo

2) 使用串口类,new一个你做的串口类,注册好串口类的数据接收器,在需要串口发送数据的地方调用串口类的发送方法,在接收器中做好对报文的校验等处理

踩坑预警

  1. 串口返回报文残缺,中间少那么一两个字节

因为你注册了两个对同一个串口的监听器,他俩在互抢

  1. 串口返回报文从中间断开

串口另一头发送的时候可能是一个字节一个字节发送的,或者一段一段发送的,不过都会在很短的时间全给你发过来,这时候最保险的做法就是收到数据时,睡上10~100ms,再读一次(接收数据实际上是你从对串口的输入流缓冲区中取出数据),然后拼上返回给外部

  1. New一个串口太吃资源

接收数据的地方其实是一个循环读取的线程,读取一次让它睡10~100ms再循环

  1. 关闭串口之后该串口读取线程还在执行

把读取线程run()里的内容拿while(){ }括起来,while条件里扔一个布尔型,默认符合条件,关闭串口时改了变量让while不符合条件,线程就自然销毁了

  1. SerialPort.java类new的时候除了串口文件和波特率之外,还要一个int型flags参数

这个我也没搞明白,学长用的时候都是写死了0传过去,没发现出问题

  1. 读取数据时inputStream.read() 方法

该方法返回值是个int,表示读到的字节数组长度,所以读的时候拿个int接着,当读完缓冲区的数据后会返回-1,所以读了之后有无数据都有返回值,所以对返回数据进一步操作前用个if括起来,int大于0再执行;

该方法传递参数有几种不同形式:

1) 传入一个byte[]容器,读到的数据存入该容器,注意不要空指针,不要超出容器容量

2) 传入一个byte[]容器,一个int型起始位置off,一个int型数据长度len,off表示读到的数据从容器的byte[off]位置开始存,len表示读len个字节存进容器,这种传参在第二次读取拼接第一次报文的地方会用到

安卓基于谷歌串口api进行串口开发的更多相关文章

  1. js基于谷歌地图API绘制可编辑圆形与多边形

    之前的工作中需要在谷歌地图上绘制可编辑多边形区域,所以基于谷歌地图API封装了个html页面,通过调用js绘制多边形并返回各点的经纬度坐标:当然首先你要保证你的电脑可以打开谷歌地图... 新建一个ht ...

  2. MSComm控件与Win32 API操作串口有何区别?

    MSComm控件与Win32 API操作串口有何区别? [问题点数:50分,结帖人shell_shell]   收藏帖子 回复 我是一个小兵,在战场上拼命!   结帖率 83.33% 我以前用MSCo ...

  3. 自己编写的基于VC++6.0的串口调试软件,并贡献源程序!

    自己编写的基于VC++6.0的串口调试软件源程序! 程序下载链接: 点击打开链接

  4. 基于微博LBS API开发的周边美图android app

    [app 不完善,就差api了] 几年之前看到过新浪微博开放API中有基于Place的API,授权后可以查看基于地理位置的一些数据,比如某个地点周边的微博动态.某个具体用户的位置动态等等.最近空余时间 ...

  5. 使用Windows API进行串口编程

    使用Windows API进行串口编程   串口通信一般分为四大步:打开串口->配置串口->读写串口->关闭串口,还可以在串口上监听读写等事件.1.打开和关闭串口Windows中串口 ...

  6. 谷歌地图 API 开发之添加标记(解析以及补充)

    今天又看了下官网,发现官网上有地图标记的详细说明.当时居然眼瞎看不见,还琢磨了好久...#$%^&,一定是项目太急,没看到(^o^)/~地址:https://developers.google ...

  7. 谷歌地图 API 开发之获取坐标以及街道详情

    自己的项目中有获取当前点击的坐标经纬度或者获取当前街道的信息的需求.估计这个对于新手来说,还是比较麻烦的,因为从官网上找这个也并不是很好找,要找好久的,运气好的可能会一下子找到. 献上自己写的测试案例 ...

  8. 记录开发基于百度地图API实现在地图上绘制轨迹并拾取轨迹对应经纬度的工具说明

    前言: 最近一直在做数据可视化方面的工作,其中平面可视化没什么难度,毕竟已经有很多成熟的可供使用的框架,比如百度的echart.js,highcharts.js等.还有就是3D可视化了,整体来说难度也 ...

  9. 基于Arduino和python的串口通信和上位机控制

    引言 经常的时候我们要实现两个代码之间的通信,比如说两个不同不同人写的代码要对接,例如将python指令控制Arduino控件的开关,此处使用串口通信是非常方便的,下面笔者将结合自己踩过的坑来讲述下自 ...

随机推荐

  1. UNP——第二章,端口号,套接字对,TCP,UDP输出

    1.端口号 端口号用于区分使用相同协议的进程. TCP69 与 UDP69 是不同的. 端口号范围 0 - 65535, 其中 0- 1023 是保留端口. 2.套接字对 TCP服务通过套接字对,唯一 ...

  2. Linux安装JAVA并且配置环境

    在写之前我先说一下我遇到的坑,我在配置环境的时候由于/etc/profile文件没有配置好导致系统彻底坏掉 1.ls vi等等命令使用不了,报错说找不到命令 2.在重启后虚拟机不能进入桌面 1.下载j ...

  3. mysql mybatis Date java时间和写入数据库时间不符差一秒问题

    1,java的数据库实体定义 private Timestamp createTime:2,非常重要!ddl语句建表字段的单位 datetime要手动设置保留3位毫秒数,不然就四舍五入了! ALTER ...

  4. LeetCode283移动零问题java高效解法

    一.题目: 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序. 示例: 输入: [0,1,0,3,12] 输出: [1,3,12,0,0] 说明: 1.必须 ...

  5. 02、Hibernate开发步骤

    1.创建Hibernate配置文件(hibernate.cfg.xml) <?xml version="1.0" encoding="UTF-8"?> ...

  6. 【进阶之路】Redis基础知识两篇就满足(二)

    导言 大家好,我是南橘,一名练习时常两年半的java练习生,这是我在博客园的第二篇文章,当然,都是要从别处搬运过来的,不过以后新的文章也会在博客园同步发布,希望大家能多多支持^_^ 这篇文章的出现,首 ...

  7. 存储型跨站获取COOKIE漏洞复现

    一.漏洞描述 获取网站cookie 二.漏洞原理 1.服务器后台写入PHP代码 $cookie = $_GET['cookie']; if($cookie){ echo ($cookie); $log ...

  8. 如何利用 CleanMyMac X 进行系统清理

    CleanMyMac X是一款颇受欢迎的专业清理软件,拥有十多项强大的功能,可以进行系统清理.清空废纸篓.清除大旧型文件.程序卸载.除恶意软件.系统维护等等,并且这款清理软件操作简易,非常好上手,特别 ...

  9. 如何用FL Studio做电音

    电音制作,自然少不了适合做电音的软件,市面上可以进行电音制作的软件不少,可是如果在这些软件中只能选择一款的话,想必多数人会把票投给FL Studio,毕竟高效率是永远不变的真理,今天就让我们来看看如何 ...

  10. 使用ABBYY FineReader 手动校正文档复杂结构

    ABBYY FineReader 15(Windows系统)拥有强大的OCR识别功能,能对扫描仪或者数码相机等光学工具获取的图像进行识别,解析其中的文本.图像.表格.条形码等,方便用户进一步获取图像中 ...