Android 模拟器串口与PC虚拟串口通讯

基于上一篇文章,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 工程

 

Android 模拟器串口与PC虚拟串口通讯_第1张图片

2、在工程的main目录下,创建jniLibs文件夹,如:E:\androidcode\SerialportNDKTest\app\src\main

jniLibs  //注意文件夹名字,不要打错,不然编译是会报错,而且非常难找

Android 模拟器串口与PC虚拟串口通讯_第2张图片

 

 

 

 

Android 模拟器串口与PC虚拟串口通讯_第3张图片Android 模拟器串口与PC虚拟串口通讯_第4张图片

3、导入相关平台Serial_Port.so 库,如我上一篇文章的生成的.so库在工程目录下

E:\androidcode\SerialPortNDK\app\build\intermediates\ndk\debug\lib

Android 模拟器串口与PC虚拟串口通讯_第5张图片

将上图lib目录的各个的.so库libserial_port.so 复制到工程“SerialPortNDKText”的jniLibs目录下。

Android 模拟器串口与PC虚拟串口通讯_第6张图片

 

Android 模拟器串口与PC虚拟串口通讯_第7张图片

 

4、添加SerialPort.java和SerialPortFinder.java文件

注意:这两个文件存放的目录必须和生成libSerialPort.so工程的相同,否则编译时,会总是报错,提示找不到xxx.so文件

(2018.8.2 补充:上面这个问题估计是新手最容易犯的,因为在JNI工程中,SerialPort.java和SerialPortFinder.java所在的包生成

生成JNI.h 文件已经包含两个java所在的包名信息,故在App 工程中,需要一致)

我第一次操作的时候,就吃了这个大亏,这个问题足足搞了3个晚上.....所以一定要注意。。。

Android 模拟器串口与PC虚拟串口通讯_第8张图片

4.1 新建serialprot 包

Android 模拟器串口与PC虚拟串口通讯_第9张图片

 

4.2 导入SerialPort.java和SerialPortFinder.java文件

Android 模拟器串口与PC虚拟串口通讯_第10张图片

4.3 在MainActivti.xml 中新建两个按钮,一个用于打开当前系统的串口,第二个用于测试发送和接收数据

Android 模拟器串口与PC虚拟串口通讯_第11张图片

5、打开模拟器命令

如果是笔记本,则一般是没有串口的,因此如果想调试串口,可以使用虚拟串口工具,如:

我使用的Configure Virtual Serial Port Driver.exe 这款软件就非常好用,如图:

Android 模拟器串口与PC虚拟串口通讯_第12张图片

5.1 我将COM1 和 COM2 虚拟出来,则表示C0M1 -> COM2 是相通的。

5.2 打开串口调试工具,如图:

Android 模拟器串口与PC虚拟串口通讯_第13张图片

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    

Android 模拟器串口与PC虚拟串口通讯_第14张图片

Android 模拟器串口与PC虚拟串口通讯_第15张图片

 

 

5.4 运行APP 

5.4.1 模拟器发送数据 -》串口助手接收数据:

Android 模拟器串口与PC虚拟串口通讯_第16张图片

5.4.2 模拟器接收数据 -》串口助手发送数据

Android 模拟器串口与PC虚拟串口通讯_第17张图片

好了,终于完成了,使用串口助手和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.(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哈

你可能感兴趣的:(Android)