一直想写一份技术文档,但由于自感能力有限而无从下笔,最近做了个关于Android平台下实现与C语言的通讯来操作蓝牙模块的项目,中间碰到了许多问题,也在网上查了许多资料,在完成主要功能后,也有一些人在网上问我一些问题,这里写下这篇文档算是一个阶段性的总结。如果反响好,后续将会发上AndroidStub与新版AndroidHAL的学习文档。

由于蓝牙模块是串口通讯机制,使用C语言来访问,而Android的应用层采用Java,无法直接操作硬件。故使用JNI的技术实现主要功能。Android的JNI应该属于AndroidHAL的一部分,由于Android的HAL机制目前还没完全摸索透,所以这里的程序架构算是老版本的HAL机制。程序架构如下图。

Android通过JNI实现与C语言的串口通讯操作蓝牙硬件模块_第1张图片

一、什么是JNI?

JNI是JavaNativeInterface的缩写,中文为JAVA本地调用。从Java1.1开始,JavaNativeInterface(JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。(以上内容摘自百度百科)

二、如何使用JNI?

1、在使用JNI之前,你要确保你的电脑中安装以下软件环境:

AndroidSDK :版本与你硬件测试环境版本相同,在Google的Android官网下载

AndroidNDK :用于编译C文件为.so的共享库,如果你是在Linux下进行开发而又具有Android的完全SDK,则不需要

Cygwin :用于编译C文件

Android开发环境 :android开发环境的配置网上一大堆,这里不再赘述

2、程序中由于只用到Java调C,而不需要C调Java,所以在应用层调C的函数很简单,只需要在一个方法前加入native关键字(native的方法不能有方法体),然后将编译的共享库导入即可。

如下:

publicclassBluetoothJNI{

static{

System.loadLibrary("jni");

}

publicnativestaticintbluetoothOn(StringstrAT);

publicnativestaticvoidbluetoothOff(StringstrAT);

publicnativestaticStringreadSerial();

publicnativestaticvoidwrite(StringstrAT);

}

3Eclipse在保存工程后,会自动把Java文件编译为class文件,我们使用javah命令把class文件编译成C头文件。如下:

Android通过JNI实现与C语言的串口通讯操作蓝牙硬件模块_第2张图片

执行此命令后将会在工程的bin目录下生成一个.h的C头文件。头文件中会生成对应Javanative方法的函数声明。新建一个与头文件同名的C文件并实现所有函数。

Android通过JNI实现与C语言的串口通讯操作蓝牙硬件模块_第3张图片

4、由于Android的底层是基于Linux内核,所以一些Windows下的系统函数不可用,Linux下的串口通讯文章网上有很多,此处代码繁多,就不贴出来了。,我们在C文件中引入jni.h与刚生成的头文件以确保JNI能调用。注意:整个程序的核心部分便是在此处,C语言与蓝牙模块的串口通讯处,我在此处碰到的问题也是最多的。

三、编译C文件

1、在Android-ndk-r5b\samples\下新建目录Bluetooth\jni,将C文件与头文件复制过来,新建Makefile。如下:

LOCAL_PATH:=$(callmy-dir)

include$(CLEAR_VARS)

LOCAL_C_INCLUDES:=$(JNI_H_INCLUDE)

LOCAL_LDLIBS:=-lm-llog

LOCAL_MODULE:=jni

LOCAL_SRC_FILES:=com_android_semisky_bluetooth_util_BluetoothJNI.c

include$(BUILD_SHARED_LIBRARY)

2、打开Cygwinbashshell,进入Bluetooth目录,执行ndk-build进行编译。

3、将libs/armeabi下生成的libjni.so文件拷入到Android工程的libs/armeabi目录下。安装apk到开发板,执行程序。

四、可能出现的问题

1、串口读写权限的问题

网上的方法是在Java中获取su账号来改权限或者在init.rc中添加命令来修改权限最后编译成img烧录进开发板,而这两种方法我都没成功,最后没办法在dos下执行shell命令来修改

2、C文件的串口读写问题

我不知道是我的程序有问题还是蓝牙模块的问题,在蓝牙模块返回数据稍大的时候,会出现数据有时返回有时不返回的情况。

3、乱码问题

蓝牙返回的数据时而出现乱码,未解决。

4、串口号的问题

如果你open的时候返回的fd小于1,确保你的开发板串口号是否正确,协议是否正确,权限是否修改。

5、最大大大的问题

读取串口代码段的算法问题,优化问题,不然数据会返回不正常。

更多相关文章

  1. Android中使用定制系统的签名文件给应用签名
  2. Android Studio中新建assets文件的两种方法
  3. Android 蓝牙对等通信初探
  4. 【Android】蓝牙开发—— 经典蓝牙配对介绍(Java代码实现演示)附De
  5. Android下的串口开发
  6. 关于Android的反编译apk文件

随机推荐

  1. MYSQL(电话号码,身份证)数据脱敏的实现
  2. MySql开发之自动同步表结构
  3. mysql升级到5.7时,wordpress导数据报错10
  4. 解决Navicat for Mysql连接报错1251的问
  5. Navicat for MySQL的使用教程详解
  6. MySQL Router实现MySQL的读写分离的方法
  7. MySQL通过binlog恢复数据
  8. MySQL 数据类型选择原则
  9. 图文详解MySQL中的主键与事务
  10. 跳槽必备之你设计索引的原则是什么?怎么