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的函數非常easy,僅僅須要在一個方法前增加nativekeyword(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);

}

 

3Eclipse在保存project后,會自己主動把Java文件編譯為class文件。我們使用javah命令把class文件編譯成C頭文件。例如以下:

 

運行此命令后將會在project的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文件拷入到Androidproject的libs/armeabi文件夾下。安裝apk到開發板。運行程序。

四、可能出現的問題

1、串口讀寫權限的問題

網上的方法是在Java中獲取su賬號來改權限或者在init.rc中加入命令來改動權限最后編譯成img燒錄進開發板。而這兩種方法我都沒成功,最后沒辦法在dos下運行shell命令來改動

2、C文件的串口讀寫問題

我不知道是我的程序有問題還是藍牙模塊的問題,在藍牙模塊返回數據稍大的時候。會出現數據有時返回有時不返回的情況。

3、亂碼問題

藍牙返回的數據時而出現亂碼,未解決。

4、串口號的問題

假設你open的時候返回的fd小於1,確保你的開發板串口號是否正確。協議是否正確,權限是否改動。

5、最大大大的問題

讀取串口代碼段的算法問題,優化問題,不然數據會返回不正常。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM