android 如何打开串口以及与串口通讯

串口通讯,对于没接触过这方面的朋友们,确实会感到头疼,不知道从何下手。
其实,串口通讯和服务器之间的通讯是一样的,都是传一些参数过去,然后返回一些数据回来。不过串口通讯管这些参数叫做指令,而这些指令是由硬件的通讯协议而定的,通讯协议不同,指令自然也不同。在我开发的这个项目里,兼容了四种硬件通讯协议,这四种协议各不相同,所以,那些指令就不在代码里面写出来了。
串口通讯,第一步要做的当然是打开串口,打开串口的方法如下:

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,以供大家参考。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,046评论 25 707
  • 串口通讯的步骤: 1.打开串口。 2.串口处于监听状态 3.想串口写入数据,串口接收到数据返回数据 串口的一个基本...
    流水线上的程序员阅读 1,465评论 1 0
  • 串口操作 串口操作需要的头文件 #include /*标准输入输出定义*/ #include /*标准函数库定...
    旅行家John阅读 1,243评论 0 3
  • 关键词:定位,调性,两个GC 读书感悟 1.定位与调性 内容运营有两个核心—定位与调性,通俗的说就是你的内容要有边...
    白木白阅读 207评论 0 0
  • 对尚侃印象最深的是岳母烧的瓦罐鸡,穿插在小洋楼里的老房子和通自来水前经常去汲水的老井。 第一次到尚侃是坐大巴,那时...
    风言无语阅读 744评论 27 67