Android通過JNI實現與C語言的串口通訊操作藍牙硬件模塊
一直想寫一份技術文檔,但由於自感能力有限而無從下筆,最近做了個關於Android平台下實現與C語言的通訊來操作藍牙模塊的項目,中間碰到了許多問題,也在網上查了許多資料,在完成主要功能後,也有一些人在網上問我一些問題,這裏寫下這篇文檔算是一個階段性的總結。如果反響好,後續將會發上Android Stub與新版Android HAL的學習文檔。
由於藍牙模塊是串口通訊機製,使用C語言來訪問,而Android的應用層采用Java,無法直接操作硬件。故使用JNI的技術實現主要功能。Android的JNI應該屬於Android HAL的一部分,由於Android的HAL機製目前還沒完全摸索透,所以這裏的程序架構算是老版本的HAL機製。程序架構如下圖。
一、 什麼是JNI?
JNI是Java Native Interface的縮寫,中文為JAVA本地調用。從Java1.1開始,Java Native Interface(JNI)標準成為java平台的一部分,它允許Java代碼和其他語言寫的代碼進行交互。JNI一開始是為了本地已編譯語言,尤其是C和C++而設計的,但是它並不妨礙你使用其他語言,隻要調用約定受支持就可以了。(以上內容摘自百度百科)
二、 如何使用JNI?
1、在使用JNI之前,你要確保你的電腦中安裝以下軟件環境:
Android SDK :版本與你硬件測試環境版本相同,在Google的Android官網下載
Android NDK :用於編譯C文件為.so的共享庫,如果你是在Linux下進行開發而又具有Android的完全SDK,則不需要
Cygwin :用於編譯C文件
Android 開發環境 :android開發環境的配置網上一大堆,這裏不再贅述
2、程序中由於隻用到Java調C,而不需要C調Java,所以在應用層調C的函數很簡單,隻需要在一個方法前加入native關鍵字(native的方法不能有方法體),然後將編譯的共享庫導入即可。
如下:
public class BluetoothJNI {
static{
System.loadLibrary("jni");
}
public native static int bluetoothOn(String strAT);
public native static void bluetoothOff(String strAT);
public native static String readSerial();
public native static void write(String strAT);
}
3、Eclipse在保存工程後,會自動把Java文件編譯為class文件,我們使用javah命令把class文件編譯成C頭文件。如下:
執行此命令後將會在工程的bin目錄下生成一個.h的C頭文件。頭文件中會生成對應Java native方法的函數聲明。新建一個與頭文件同名的C文件並實現所有函數。
4、由於Android的底層是基於Linux內核,所以一些Windows下的係統函數不可用,Linux下的串口通訊文章網上有很多,此處代碼繁多,就不貼出來了。,我們在C文件中引入jni.h與剛生成的頭文件以確保JNI能調用。注意:整個程序的核心部分便是在此處,C語言與藍牙模塊的串口通訊處,我在此處碰到的問題也是最多的。
三、編譯C文件
1、在Android-ndk-r5b\samples\下新建目錄Bluetooth\jni,將C文件與頭文件複製過來,新建Makefile。如下:
LOCAL_PATH := $(call my-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、打開Cygwin bash shell,進入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、最大大大的問題
讀取串口代碼段的算法問題,優化問題,不然數據會返回不正常。
最後更新:2017-04-03 07:56:55