閱讀44 返回首頁    go 阿裏雲 go 技術社區[雲棲]


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);

}

 

3Eclipse在保存工程後,會自動把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

  上一篇:go Swift學習之十三:函數(Functions)
  下一篇:go linux下at&t匯編下的編程編譯體會