首先是Google的demo,
https://code.google.com/p/android-serialport-api/
但是这是个很老的demo,因此是eclipse上的。
现在要在Android studio使用此demo:
下面简单介绍一下我所做的,说是简单介绍,因为还有些问题没有搞明白,还望路过的高手指点一下。
同时也希望能帮助初学的同学跑通程序。
试验时间:2015年10月
首先贴出一个官方文档
http://tools.android.com/tech-docs/new-build-system/gradle-experimental
文档还是很简单明了的,注意其中标为红色的地方,是看似多余但是很重要的固定格式
文档末尾有sample的链接,不过那个sample下来后我不知道怎么用,每个项目是一个module,不知道怎么run起来(希望大家帮助),只参考了下代码。
说重点:
- gradle 目前只能(注意是Only) 用2.5的版本。
- Android NDK r10e
- build tools 用的是 gradle-experimental:0.2.0
需要特别修改的大致有下面几处:
详细步骤:
1.gradle->wrapper->gradle-wrapper.properties 文件中:
gradle版本号改为2.5
distributionUrl=https\://services.gradle.org/distributions/gradle-2.5-all.zip
我使用的是本地的gradle,还要在studio的preference里配置下;
2.NDK 在studio的preference里配置好路径就可以,或者可以手动去local.properties文件里加;
3.在project的build.gradle中:
将 classpath 'com.android.tools.build:gradle:1.3.0' 改为:
classpath 'com.android.tools.build:gradle-experimental:0.2.0'
4.App下的build.gradle改动较多一些,请参考文档中的红字:
http://tools.android.com/tech-docs/new-build-system/gradle-experimental
这里贴一个可用的简短的版本:
apply plugin: 'com.android.model.application'
model {
android {
//编译的SDK版本要与硬件的SDK版本一致,否则会导致termios.h调用出错
// but,why sdk的版本会影响到编译出的so中的函数?原因在查ing
compileSdkVersion = 18
buildToolsVersion = "23.0.1"
defaultConfig.with {
applicationId = "com.meican.serialport"
minSdkVersion.apiLevel = 14
targetSdkVersion.apiLevel = 18
versionCode = 1
versionName = "1.0"
}
}
android.buildTypes {
release {
minifyEnabled = false
proguardFiles += file('proguard-rules.pro')
}
}
android.ndk {
moduleName = "serial_port"
}
}
5.从官方demo中拷贝出需要的class,例如:SerialPort.class,SerialPortFinder.class等
如我截图那样就够了,只有MainActivity是自己的,而且继承了SerialPortActivity。
6.在main文件目录下,建一个JNI文件夹
在次文件夹下可以建一个sh脚本,当然不写脚本也可以,脚本其实就是用来执行javah的。脚本header_file.sh如下:
#!/usr/bin/env bash
export ProjectPath=$(cd "../$(dirname "$1")"; pwd)
export TargetClassName="com.meican.serialport.api.SerialPort(调用native函数的类的路径)"
export SourceFile="${ProjectPath}/java"
export TargetPath="${ProjectPath}/jni"
cd "${SourceFile}"
javah -d ${TargetPath} -classpath "${SourceFile}" "${TargetClassName}"
echo -d ${TargetPath} -classpath "${SourceFile}" "${TargetClassName}"
运行此脚本。即可生成.h文件,文件名可以自己重新命名。
注意: 上面的:TargetClassName = xxx.xxx.xxx.class 这个类中要先调用native函数,头文件中才会生成对应的函数
// JNI
private native FileDescriptor open(String path, int baudrate, int flags);
public native void close();
然后把官方demo中的.c 复制过来。
搞定 End
-
可能遇到的Error
运行后崩溃,termios.h 这个库中的 tcsetattr 函数报错。
解决办法: 要将编译的SDK版本设为与测试机的 SDK版本相同
( 这个问题搞了好久才找到解决办法,但是还是不明白,为什么编译出的so库里函数的调用受到SDK的版本影响,应该是受NDK影响啊?
感觉此解决办法是歪打正着,还望路过的诸位大神指点!!!) -
没有读写权限
我是手机连接了一个USB转接的串口进行的调试,手机和电脑是WiFi连接的,手机已rootadb shell //进入手机 su //root权限 cd dev/ //进入dev文件夹,听说也可能不在这个文件夹(我也不确定,求指点) //找到对应的串口,例如:ttyUSB0 chmod 777 ttyUSB0
// 777 代表的是权限
详见 http://blog.chinaunix.net/uid-25052030-id-174343.html
补充:(2015年12月21日)
因为experimental的版本很多不支持,例如单元测试,所以在gradle.properties 中加入 android.useDeprecatedNdk=true,可以使用旧的的ndk。这样build.gradle就可以按照正常写法写了。