串口通讯,对于没接触过这方面的朋友们,确实会感到头疼,不知道从何下手。

其实,串口通讯和服务器之间的通讯是一样的,都是传一些参数过去,然后返回一些数据回来。不过串口通讯管这些参数叫做指令,而这些指令是由硬件的通讯协议而定的,通讯协议不同,指令自然也不同。在我开发的这个项目里,兼容了四种硬件通讯协议,这四种协议各不相同,所以,那些指令就不在代码里面写出来了。

串口通讯,第一步要做的当然是打开串口,打开串口的方法如下:

QQ截图20161211220537.png

首先在app下建立一个libs文件夹,把.so文件复制到libs下

QQ截图20161211220537.png

用android studio的朋友们要记得在build.gradle 文件中添加这段 jniLibs.srcDirs = ['libs'] ,我有一次看见别人的代码里面可以不加这段,照样能运行,有知道的可以和大家分享一下。不过这些都不重要,只要能开串口就行。然后,在java的根目录下建一个包,注意是根目录,包名为:android_serialport_api,这个包名是固定的,不能少也不能多。然后把类SerialPort复制到包下面。

// JNI

private native static FileDescriptor open(String path, int baudrate, int flags);

public native void close();

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

上面的第一个函数open是调用jni打开串口的方法,调用该方法的时候会返回一个FileDescriptor对象,通过该对象可以获取输入输出流。第二个close函数是关闭串口的方法,可以通过此方法关闭串口。这两个函数最好是能成对出现,在程序打开的时候把串口打开,程序退出了就把串口关闭,这样可以避免一些问题出现。第三个是加载.so文件里面的代码的,加载了之后串口才能用。

···

public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException {

System.out.println("device======"+device.getAbsolutePath());

/* Check access permission /

if (!device.canRead() || !device.canWrite()) {

try {

/ Missing read/write permission, trying to chmod the file */

Process su = Runtime.getRuntime().exec("/system/bin/su");

String cmd = "chmod 666 " + device.getAbsolutePath() + "\n"

+ "exit\n";

su.getOutputStream().write(cmd.getBytes());

if ((su.waitFor() != 0) || !device.canRead()

|| !device.canWrite()) {

throw new SecurityException();

}

} catch (Exception e) {

e.printStackTrace();

throw new SecurityException();

}

}

mFd = open(device.getAbsolutePath(), baudrate, flags);

if (mFd == null) {

Log.e(TAG, "native open returns null");

throw new IOException();

}

mFileInputStream = new FileInputStream(mFd);

mFileOutputStream = new FileOutputStream(mFd);

}

···

上面的这段代码中,su.getOutputStream().write(cmd.getBytes());这行是获取root权限的,打开串口是需要root权限的,如果不能获取root权限,串口也是打不开的,其他的就是一些判断了,在这就不做详细讲解了。

上面这些是开串口之前的准备,准备完毕后,我们来打开串口,打开串口就是调用open函数,调用open函数需要传三个参数,第一个参数path是串口名,比如:”/dev/ttyS0“,这些是根据实际接口来定的,第二个参数baudrate是波特率,一般都是9600,15200,这个需要根据硬件来定,第三个我就不清楚了,我都是传0,有知道的可以和大家分享一下。

···

/**

* 初始化串口

* @param lockerPortInterface

/

private void setSerialPort(LockerPortInterface lockerPortInterface){

this.sportInterface = lockerPortInterface;

try {

/ Check parameters /

if ((path.length() == 0) || (baudrate == -1)) {

throw new InvalidParameterException();

}

/ Open the serial port */

boxPort = new SerialPort(new File(path), baudrate, 0);

mOutputStreamBox = boxPort.getOutputStream();

mInputStreamBox = boxPort.getInputStream();

/* Create a serial rec buf thread */

mReadThreadBox = new ReadThreadBox();

// SerialPortState = true;

mReadThreadBox.start();

if (firstRegisterBox) {

if(mContext == null){

Log.e(TAG, "mContext nulll");

}

m_SerialRecBox = new SerialBroadcastReceiverBox(mContext);

m_SerialRecBox.registerAction();

firstRegisterBox = false;

Log.i(TAG, "----locker port--- 注册完毕");

}

lockerPortInterface.onLockerOutputStream(mOutputStreamBox);

} catch (SecurityException e) {

e.printStackTrace();

DisplayError(mContext,R.string.error_security);

} catch (IOException e) {

e.printStackTrace();

DisplayError(mContext,R.string.error_unknown);

} catch (InvalidParameterException e) {

e.printStackTrace();

DisplayError(mContext,R.string.error_configuration);

}

}

···

boxPort = new SerialPort(new File(path), baudrate, 0);这行代码是调用SerialPort的构造方法,通过他的构造方法去调用open函数,然后通过SerialPort对象来获取输入输出流。在这里解释一下,输入流是接收串口返回的数据,输出流是向串口发指令。 调用SerialPort的构造方法可能会发生三种异常,第一种异常(SecurityException)是串口无读写权限,抛出这种异常的话就说明你可能没有root权限,第二种异常(IOException )串口不能打开,可能就是你没有这个串口,第三种异常(InvalidParameterException)是传的参数有误,可能是你的波特率不对。我理解的就是这样的,不知道对不对。

openserialport.gif

这是我用模拟器测试的,只要有请求root权限的页面,并且抛的是IO异常,打开串口应该就没问题了。

最后就是向串口发指令,向串口发指令是用输出流向串口写入,至于具体的指令是什么,需要根据协议来定。发完指令之后串口会回数据结果给你,你需要接收这些数据来做业务,硬件不同,回数据结果的方式也不同,有些硬件是发完指令后把结果直接回给你,有些硬件是先给你一小部分,然后等1s再回另外一部分数据。

在我写的demo里面用的方法是针对硬件一次性把数据结果全部返回的方式,onLockerDataReceived直接用这个方法接收数据,这样就比较简单了。串口通讯说到这里就结束了。

最后贴上自己写的一个小demo地址:https://github.com/fm183/SerialportDemo.git,以供大家参考。

android 串口一直打开_android 如何打开串口以及与串口通讯相关推荐

  1. android 串口一直打开_Android串口使用总结

    准备工作 NDK环境 串口通信使用的C文件 注意:c文件中需要修改函数名为当前包名的路径,c文件和.h头文件都需要修改 接入底层库 使用SO库引入 main目录下新建jni录,将C文件置于该处 新建A ...

  2. Win 10系统下,用stc-isp烧程序的时候,出现“串口已被其它程序打开或该串口不存在”的解决方法

    最近刚刚入手51单片机开发,本人使用的是Win 10系统,本来已经写好程序了,很开森地准备使用stc-isp进行程序烧写,结果大失所望,提示出现"串口已被其它程序打开或该串口不存在" ...

  3. android studio在夜神上打开_Android Studio之使用连接夜神模拟器分析Smail 【详文】8.7日更正...

    本帖最后由 Jxdm 于 2018-8-7 09:31 编辑 前言: 想把一个APP去广告,结果发现修改关键代码后出现崩溃,于是就想到了动态调试.由于是第一次使用,百度了N个网页,然后慢慢摸索才知道是 ...

  4. 【Android 高性能音频】Oboe 音频流打开后 耳机 / 音箱 插拔事件处理 ( 动态注册广播接收者监听耳机插拔事件 | 重新打开 Oboe 音频流 )

    文章目录 一.动态注册广播接收者监听耳机插拔事件 二.jni 层的 Oboe 播放器代码 ( 重新打开 Oboe 音频流 ) 三.相关资料 基于 [Android 高性能音频]Oboe 开发流程 ( ...

  5. android 将IE设为默认打开的浏览器

      这个其实和android没有什么太大的关系,只是之前几次下载Google浏览器时,系统默认修改为了Google浏览器.但是自己习惯了IE浏览器,所以想把它设置回来.但是自己居然不知道怎么做 ...

  6. android app没有读写权限设置,Android 6.0以上权限拒绝打开权限设置界面的解决方法...

    本人使用小米手机,打开qq或者微信的时候,某个权限拒绝的话,会提示你开启,点击开启会跳转到app的权限设置界面,当然了,这是国内系统深层定制的原因,也就是说这个界面原声的android没有的!这里以小 ...

  7. android点击另一个app,Android 怎么从一个APP中打开另外一个APP

    Android 如何从一个APP中打开另外一个APP 众所周知,在一个APP内部,从一个页面跳转到另外一个页面是使用startactivity函数来实现的. 同样的,对于应用之间的跳转也是如此的.应用 ...

  8. Android安装后没有完成和打开按钮

    File apkFile = new File(filePath);Intent intent = new Intent();intent.setFlags(Intent.FLAG_ACTIVITY_ ...

  9. android系统中如何通过程序打开某个AccessibilityService

    android系统中如何通过程序打开某个AccessibilityService(系统辅助服务)? 通常的做法是注册AccessibilityService(辅助服务)后跳转到设置启动服务页面引导用户 ...

最新文章

  1. 趣头条基于Flink+ClickHouse的实时数据分析平台
  2. OpenERP Web开发
  3. 史上最全 Python Re 模块讲解(三)
  4. 十分钟玩转 jQuery、实例大全
  5. nodejs mysql 返回json_python向mysql中存储JSON及Nodejs取出
  6. python 3.5 format_Python3 format及字符串格式化
  7. php orm教程,Laravel ORM 数据model操作教程
  8. Ubuntu 16.04 软件安装
  9. 《机器学习Python实践》第3章——第一个机器学习项目
  10. 利用ffmpeg解析视频文件信息
  11. redis的过期策略【转】
  12. 万字超详细图文教程:联想G510加装内存条、固态,机械移至光驱位
  13. HI3519 开发交流QQ群
  14. SNI(Server Name Indication)
  15. 如何理解互联网轻资产创业?
  16. javaweb实现支付宝扫码支付完整流程
  17. GNS3-GREvpn
  18. 即将升级的LDK7.1支持云授权了
  19. PHP 自由职业,自由职业者:不止自由,更多自我
  20. 传奇服务器人物技能怎么修改,如何修改传奇服务器中角色等级相关系统

热门文章

  1. metadata request forward to GM6 - X-DevTools-Emulate-Network-Conditions-Cli
  2. Make Membership header extension fields editable
  3. SAP CM: cl_crm_oi_docx_transform_rt=indicate_tree
  4. pom.xml dependency依赖的研究
  5. 乾坤大挪移:SAP CRM WebClient UI 和 SAP Fiori UI 混搭并存
  6. java数组求和递归,js数组去重 数组拼接 替换数组中的指定值 递归数组 判断数组中是否存在指定值 数组求和 根据条件判数组值...
  7. 在计算机的通信子网中 其操作方式有两种,全国自考计算机网技术模拟试卷(八)及答案.doc...
  8. Python 基本输出
  9. golang语言变量定义、打印、占位符
  10. python摄像头人脸识别代码_python 实现摄像头人脸识别