基于上一篇文章,Android studio 使用NDK 实现串口 动态库 使用NDK生成.so 库操作PC中的串口
以及Android studio 3.0 and Gradle3.0 JNI 生成.so 库。
1、开发环境
(1) Android Studio 3.0.1 (2) JDK 1.8 (3)
1、创建SerialPortNDKText 工程
2、在工程的main目录下,创建jniLibs文件夹,如:E:\androidcode\SerialportNDKTest\app\src\main
jniLibs //注意文件夹名字,不要打错,不然编译是会报错,而且非常难找
3、导入相关平台Serial_Port.so 库,如我上一篇文章的生成的.so库在工程目录下
E:\androidcode\SerialPortNDK\app\build\intermediates\ndk\debug\lib
将上图lib目录的各个的.so库libserial_port.so 复制到工程“SerialPortNDKText”的jniLibs目录下。
4、添加SerialPort.java和SerialPortFinder.java文件
注意:这两个文件存放的目录必须和生成libSerialPort.so工程的相同,否则编译时,会总是报错,提示找不到xxx.so文件
(2018.8.2 补充:上面这个问题估计是新手最容易犯的,因为在JNI工程中,SerialPort.java和SerialPortFinder.java所在的包生成
生成JNI.h 文件已经包含两个java所在的包名信息,故在App 工程中,需要一致)
我第一次操作的时候,就吃了这个大亏,这个问题足足搞了3个晚上.....所以一定要注意。。。
4.1 新建serialprot 包
4.2 导入SerialPort.java和SerialPortFinder.java文件
4.3 在MainActivti.xml 中新建两个按钮,一个用于打开当前系统的串口,第二个用于测试发送和接收数据
5、打开模拟器命令
如果是笔记本,则一般是没有串口的,因此如果想调试串口,可以使用虚拟串口工具,如:
我使用的Configure Virtual Serial Port Driver.exe 这款软件就非常好用,如图:
5.1 我将COM1 和 COM2 虚拟出来,则表示C0M1 -> COM2 是相通的。
5.2 打开串口调试工具,如图:
5.3 将模拟器绑定到Windows 的虚拟串口COM1 映射到Android 模拟器中,(提示,我调试使用的Android 模拟器版本是4.4 对应API 版本
API19,而Android 5.0 以上的系统由于安全权限不一样,当运行SerialPort类的构造方法中下面代码,则会提示没有权限)
/* Check access permission */
if (!device.canRead() || !device.canWrite()) {
try {
/* Missing read/write permission, trying to chmod the file */
Process su;
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();
}
}
对于上面的问题,目前本人还是个菜鸟新人,还没有找到解决办法,如果有大神知道,可以给小弟提点意一下。
接着,win + r 打开window 控制台,输入映射命令
映射的命令是:emulator @模拟器名字 -qemu -serial COMX(电脑串口号)
如我的,emulator @api -qemu -serial COM1
5.4 运行APP
5.4.1 模拟器发送数据 -》串口助手接收数据:
5.4.2 模拟器接收数据 -》串口助手发送数据
好了,终于完成了,使用串口助手和Android模拟器互相收发数据。
但是,目前还是存在三个没有弄清楚的问题,有待解决。
第一个:就是使用模拟器,串口最大接收的字节数是8字节,超过这个数值模拟器就是类似死掉,毫无反应。
第二个:就是串口号与Linux 系统中的ttySxxxx 对应问题,如果映射的Windows串口号与app 打开串口对不上,则会出现
下面的错误:tcgetattr() failed
D/serial_port: Opening serial port /dev/ttyS2 with flags 0x2
D/serial_port: open() fd = 46
D/serial_port: Configuring serial port
E/serial_port: tcgetattr() failed
E/SerialPort: nativeopen returns null
W/System.err: java.io.IOException
W/System.err: at chenxi.com.serialportjni.SerialPort.<init>(SerialPort.java:64)
W/System.err: at chenxi.com.serialportndktest.MainActivity$2.onClick(MainActivity.java:105)
W/System.err: at android.view.View.performClick(View.java:4438)
W/System.err: at android.view.View$PerformClick.run(View.java:18422)
W/System.err: at android.os.Handler.handleCallback(Handler.java:733)
W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
有些电脑使用的是网上很多使用的是 ttyS2, 而在我的模拟器上就会出现上面的问题,进过多次尝试,使ttyS1 才能正常收发数据,这个问题需要再查查资料。
(2018.8.2 补充: 之前没有把Linux 与 Android 联系起来,所以才没有把这个疑问给想通,最近,在公司做项目需要做三个平台的开发包Windows、Linux 和 Android,于是查看Linux 串口一些资料,发现一般的:
1、查看串口是否可用:可以对串口发送数据比如对com1口,echo /dev/ttyS0
2、在Linux查看串口名称使用
ls -l /dev/ttyS*
一般情况下串口的名称全部在dev下面,如果你没有外插串口卡的话默认是dev下的ttyS*,一般ttyS0对应com1,ttyS1对应com2,当然也不一定是必然的;
而且在上面的 5.3提到 我是”将模拟器绑定到Windows 的虚拟串口COM1 映射到Android 模拟器中“”所以,才有在打开串口是需要使用的是ttyS1)
第三个:就是使用root的权限修改串口权限,有两种情况,
(1)
su = Runtime.getRuntime().exec("/system/xbin/su");
(2)
su = Runtime.getRuntime().exec("/system/bin/su");
上面三个问题,还需要,多查查资料才行。
OK, 终于完成了。开心!!!!!!!!!!O(∩_∩)O哈