准备材料

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. bluestore对象挂载到系统进行提取

    前言 之前在filestore里面,pg是直接暴露到文件系统的,也就是可以直接进去查看或者拷贝,在极端情况下,多个osd无法启动,pg无法导出的时候,那么对pg内部对象的操作处理,是可以作为最后恢复数 ...

  2. 处理ceph incompelete的经验

    前言 最近已经见到几个环境出现过incompelete了,这个在很久以前Jewel正在合入mark-complete工具的时候就有做过类似的处理,但是随着处理的环境越来越多,这个地方还是有些需要注意的 ...

  3. asp.net core 使用 TestServer 来做集成测试

    asp.net core 使用 TestServer 来做集成测试 Intro 之前我的项目里的集成测试是随机一个端口,每次都真实的启动一个 WebServer,之前也有看到过微软文档上 TestSe ...

  4. 【Python】Json序列化和反序列化模块dumps、loads、dump、load函数介绍

    1.json.dumps()  json.dumps()用于将dict类型的数据转成str,因为如果直接将dict类型的数据写入json文件中会发生报错,因此在将数据写入时需要用到该函数. 转换案例: ...

  5. CentOS 7 静态IP配置

    CentOS 7 网络配置还有一个有趣的现象,我们都习惯使用 ifconfig 命令查看自己的网络信息和IP地址,但是在 CentOS 7 是无法执行的,如下图所示: 原因是 CentOS 7 使用 ...

  6. cdh中jps显示process information unavailable问题的解决

    百度的方法有两种: 第一种 1.进入/tmp 2.删除该目录下的hsperfdata_${username} 文件夹 3.再执行jps 第二种 做软连接 或者修改权限hsperfdata_${user ...

  7. MindManager使用教程:如何导出HTML5交互式导图

    Mindmanager思维导图软件有着友好的用户界面以及丰富的思维导图制作功能.再搭配与Microsoft 软件的无缝集成功能,使得这款思维导图软件越来越受到职场人士的喜爱. 不仅是作为制作思维导图的 ...

  8. CorelDRAW X7 X8 2017 2018是什么关系?

    从CorelDRAW 2017版本开始我们叫习惯了的X几系列的CorelDRAW毅然决然的就换了称呼,所以有时候很多朋友对于软件版本,经常会傻傻分不清,还有人认为X8版本比2017版本高,究竟为什么会 ...

  9. CorelDRAW快速制作闪耀钻石项链效果

    今天小编为大家分享使用CorelDRAW快速制作闪耀钻石项链效果,过程并不是很复杂,主要用到刻刀工具.智能填充和渐变色的应用,待到一个角完成之后会走一点点捷径,利用旋转复制的方法做出完整的钻石效果,最 ...

  10. csust T1097 “是时候表演真正的技术了” 题解(虚点跑最短路)

    题目链接 题目大意 给你n个点m条路,以及k个宝藏点,q次查询要你求出距离这个点最近的宝藏点的距离 题目思路 一个套路题,建立虚点与k个点连一个权值为0的边,跑最短路即可 注意边多了4000条 代码 ...