Android SerialPort Api 打开端口失败,tcsetattr返回-1的解决方法

之前的一份代码,最近编译后突然打不开串口了,几经周折,终于解决,调试分析过程如下(安卓操作串口使用的是Google开源的那个android_serialport_api库):

开始调试就发现,在SerialPort.java的构造函数的:

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

返回了null,而open是个native函数,也就是问题是出在本地库上(.so)。

跟入本地库,发现在SerialPort.c的open函数的:

if (tcsetattr(fd, TCSANOW, &cfg))

返回的-1,errno为25。

百思不得解,串口部分模块在测试成功之后正常工作了很久,也没有改动过,而且硬件环境也未变更,系统也未更新过。怎么会出问题在这个奇怪的地方。上网查了一些资料后发现也有类似的情况:http://www.jianshu.com/p/050875e3a7d4

说重点:

  • gradle 目前只能(注意是Only) 用2.5的版本。
  • Android NDK r10e
  • build tools 用的是 gradle-experimental:0.2.0
  • ……

可能遇到的Error
运行后崩溃,termios.h 这个库中的 tcsetattr 函数报错。
解决办法: 要将编译的SDK版本设为与测试机的 SDK版本相同
( 这个问题搞了好久才找到解决办法,但是还是不明白,为什么编译出的so库里函数的调用受到SDK的版本影响,应该是受NDK影响啊?
感觉此解决办法是歪打正着,还望路过的诸位大神指点!!!

根据文章所述,tcsetattr返回错误的原因是编译的SDK版本与目标SDK版本不符。

这个理由在我的项目中根本不成立,因为之前串口调试成功时,编译的目标SDK版本也是大于实际设备的SDK版本的。但这些内容也不是完全没有用,反复查看了上面的内容之后,感觉问题的主要原因应该是出在gradle或者NDK的版本上。

但因为这个就去修改gradle或者ndk的版本有点太兴师动众了。所以想看看拿之前编译的so库文件直接添加到项目中,而不是每次编译生成so库,这样能否解决问题。

添加了编译好的so库,并删除了C相关的代码,构建好APK,上机测试,终于恢复正常!

《Android SerialPort Api 打开端口失败,tcsetattr返回-1的解决方法》有2条评论

  1. 遇到了同样的问题,那问题真是恶心啊…照着博主的思路实现了,这个问题该是Android Studio NDK编译链的问题还是系统的问题啊?

    回复

发表评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据