Android UART 串口通信

1. 需求

最近有項目需要實現(xiàn)windows機器和Android開發(fā)版進(jìn)行UART串口通信刊头,經(jīng)過3天查找嘗試豁延,特記錄一下最終方案,希望之后的同行少走彎路腔召,最后在git上回開源我最終的方案希望大家支持轧葛。

2. 環(huán)境

Android 3.0.1
Gradle 4.1
ARM開發(fā)版 : RK3399
PC機器:Win10
開發(fā)機器:MAC 10.13.3

3. 解決方法

  1. Android Things

    Android Things 谷歌于2018年5月發(fā)布1.0正式版搂抒,讓開發(fā)者可以使用Android開發(fā)工具開發(fā)嵌入式設(shè)備。需要比較高的Android API支持 ( >24 )尿扯。很多樹莓派3用這個做開發(fā)求晶,普遍應(yīng)用于物聯(lián)網(wǎng)領(lǐng)域。

    因為是官方的原因衷笋,感覺應(yīng)該靠譜些誉帅,且集成方便,Git上參考了https://github.com/androidthings/sample-uartloopback這個項目右莱。但是,每個卵用档插。簡直白折騰慢蜓。首先需要API 27以上的設(shè)備,現(xiàn)在手上的開發(fā)版很少有Android 8.0以上版本的郭膛。(為此晨抡,還刷了固件,做了嘗試)最大的坑是:這個項目最后基本安裝不到國內(nèi)的Android 系統(tǒng)上,原因:需要Google Service耘柱。強依賴<uses-library android:name="com.google.android.things"/>如捅。考慮日后上線產(chǎn)品的維護(hù)调煎,果斷放棄镜遣。

  2. android-serialport-api

    android-serialport-api,是兩個Eclipse項目士袄,導(dǎo)入進(jìn)去之后悲关,設(shè)置好設(shè)備和波特律之后直接就可以使用,也看到別人分享的項目經(jīng)驗娄柳,這個可用寓辱。具體講解可以參考這篇文章https://blog.csdn.net/qiwenmingshiwo/article/details/49557889,兩個項目分別是編譯底層JNI項目android-sercd赤拒,另一個側(cè)重根據(jù)JNI的API實現(xiàn)Java端功能秫筏。如果只實現(xiàn)功能就看android-serialport-api

    缺點:項目比較老,需要JNI編譯

    經(jīng)過嘗試導(dǎo)入庫中已編譯好的so挎挖,運行可以跑通UART通信这敬。但遇到了一下幾個‘坑’ 導(dǎo)入JNI的時候注意事項就不說了,包名這些的都不能改肋乍。

    • Run 使用已有的so的項目時候會報錯 dlopen failed: "has text relocations"

    • 遇到無法獲取port鹅颊,請重新配置Serial port類似的報錯

    解決方法:

    1. 關(guān)于dlopen failed: "has text relocations" 的簡單解決辦法,降級targetSdkVersion 23一下墓造。Android 6.0 機制的問題堪伍。根本解決版本使用高版本的NDK重新編譯so來解決,后文中我重新編譯了一把觅闽。這里是gradle文件修改的關(guān)鍵地方帝雇。

      compileSdkVersion 22
      defaultConfig {
           applicationId "com.attrsc.braincs.androidserialport"
           minSdkVersion 21
           targetSdkVersion 22
           versionCode 1
           versionName "1.0"
           testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
      
           ndk {
               abiFilters "armeabi-v7a"
           }
       }
      
    2. 關(guān)于無法獲取port的報錯

      一開始我懷疑是我的so沒有加載成功,后來斷點發(fā)現(xiàn)無法從sharePreference中獲取到設(shè)置的 Device和baudrates蛉拙。修改SerialPortPreferencesActivity如下:

       public class SerialPortPreferences extends PreferenceActivity {
      
           private Application mApplication;
           private SerialPortFinder mSerialPortFinder;
      
           @Override
           protected void onCreate(Bundle savedInstanceState) {
               super.onCreate(savedInstanceState);
      
               mApplication = (Application) getApplication();
               mSerialPortFinder = mApplication.mSerialPortFinder;
      
               addPreferencesFromResource(R.xml.serial_port_preferences);
               final SharedPreferences sp = getSharedPreferences("android_serialport_api.sample_preferences", MODE_PRIVATE);
      
               // Devices
               final ListPreference devices = (ListPreference)findPreference("DEVICE");
               String[] entries = mSerialPortFinder.getAllDevices();
               String[] entryValues = mSerialPortFinder.getAllDevicesPath();
               devices.setEntries(entries);
               devices.setEntryValues(entryValues);
               devices.setSummary(devices.getValue());
               devices.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
                     public boolean onPreferenceChange(Preference preference, Object newValue) {
                       preference.setSummary((String)newValue);
                       sp.edit().putString("DEVICE",(String) newValue).apply();//此處添加
                       return true;
                   }
               });
      
               // Baud rates
               final ListPreference baudrates = (ListPreference)findPreference("BAUDRATE");
               baudrates.setSummary(baudrates.getValue());
               baudrates.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
                   public boolean onPreferenceChange(Preference preference, Object newValue) {
                       preference.setSummary((String)newValue);
                       sp.edit().putString("BAUDRATE",(String) newValue).apply();//此處添加
                       return true;
                   }
               });
          }
       }
      
       ?```  
      
      

4. 終極解決方案

先上圖

android_menu.png
android_talk.png
pc-comm.png
pc-receive.png

由于android-serialport-api項目中的so使用較old的ndk編譯尸闸,所以在對于Android 6.0 以上版本兼容的時候會報錯dlopen failed: "has text relocations"。且使用的mk進(jìn)行編譯孕锄,特升級為用cmake編譯吮廉。

升級android-serialport-api

  • ndk 17.0.4xxx jni編譯

  • cmake 編譯鏈

  • EClipse項目-> Android Studio項目

項目結(jié)構(gòu):

.
├── AndroidSerialLibrary.iml
├── androidserial
│   ├── CMakeLists.txt
│   ├── androidserial.iml
│   ├── build
│   ├── build.gradle
│   ├── libs
│   ├── proguard-rules.pro
│   └── src
├── app
│   ├── app.iml
│   ├── build
│   ├── build.gradle
│   ├── libs
│   ├── proguard-rules.pro
│   └── src
├── build
│   └── android-profile
├── build.gradle
├── gradle
│   └── wrapper
├── gradle.properties
├── gradlew
├── gradlew.bat
├── local.properties
└── settings.gradle

app對應(yīng)原項目中的各個Activity, androidserial 是module 對應(yīng)編譯之前的so畸肆,還有API的封裝宦芦。可以直接引用androidserial轴脐,調(diào)用方法參考app目錄下的activity调卑。

注意關(guān)于權(quán)限抡砂!

當(dāng)接入開發(fā)板后如果發(fā)現(xiàn) Error You do not have read/write permission to the serial port 需要root 權(quán)限,在開發(fā)者模式中開啟root 權(quán)限 adb和應(yīng)用

使用一下命令開啟Android對串口的讀寫權(quán)限

? adb shell 
 rk3399_firefly_mid:/ $ su
 rk3399_firefly_mid:/ # chmod 777 /dev/ttyS4
 rk3399_firefly_mid:/ # setenforce 0 
 rk3399_firefly_mid:/ # 

setenforce 0: 關(guān)閉防火墻恬涧,有人說關(guān)鍵是這注益,但是我的環(huán)境不用關(guān)閉,只要給權(quán)限就可以

注意關(guān)于ttyS1 - 6 ttyS1 - 6 對應(yīng)的是 UART 串口1-6 一般都是一一對應(yīng)的溯捆。這個具體要看一下開發(fā)板的說明丑搔。

記錄的比較糙,還請見諒现使,如有問題請留言低匙,我看到后肯定回復(fù)。項目主要看結(jié)構(gòu)碳锈,剩下的都是復(fù)制黏貼的事顽冶。git地址:https://github.com/braincs/AndroidSerialLibrary

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市售碳,隨后出現(xiàn)的幾起案子强重,更是在濱河造成了極大的恐慌,老刑警劉巖贸人,帶你破解...
    沈念sama閱讀 223,002評論 6 519
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件间景,死亡現(xiàn)場離奇詭異,居然都是意外死亡艺智,警方通過查閱死者的電腦和手機倘要,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,357評論 3 400
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來十拣,“玉大人封拧,你說我怎么就攤上這事∝参剩” “怎么了泽西?”我有些...
    開封第一講書人閱讀 169,787評論 0 365
  • 文/不壞的土叔 我叫張陵,是天一觀的道長缰趋。 經(jīng)常有香客問我捧杉,道長,這世上最難降的妖魔是什么秘血? 我笑而不...
    開封第一講書人閱讀 60,237評論 1 300
  • 正文 為了忘掉前任味抖,我火速辦了婚禮,結(jié)果婚禮上灰粮,老公的妹妹穿的比我還像新娘非竿。我一直安慰自己,他們只是感情好谋竖,可當(dāng)我...
    茶點故事閱讀 69,237評論 6 398
  • 文/花漫 我一把揭開白布红柱。 她就那樣靜靜地躺著,像睡著了一般蓖乘。 火紅的嫁衣襯著肌膚如雪锤悄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,821評論 1 314
  • 那天嘉抒,我揣著相機與錄音零聚,去河邊找鬼。 笑死些侍,一個胖子當(dāng)著我的面吹牛隶症,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播岗宣,決...
    沈念sama閱讀 41,236評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼蚂会,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了耗式?” 一聲冷哼從身側(cè)響起胁住,我...
    開封第一講書人閱讀 40,196評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎刊咳,沒想到半個月后彪见,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,716評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡娱挨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,794評論 3 343
  • 正文 我和宋清朗相戀三年余指,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片跷坝。...
    茶點故事閱讀 40,928評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡酵镜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出探孝,到底是詐尸還是另有隱情笋婿,我是刑警寧澤,帶...
    沈念sama閱讀 36,583評論 5 351
  • 正文 年R本政府宣布顿颅,位于F島的核電站缸濒,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏粱腻。R本人自食惡果不足惜庇配,卻給世界環(huán)境...
    茶點故事閱讀 42,264評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望绍些。 院中可真熱鬧捞慌,春花似錦、人聲如沸柬批。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,755評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至嗅虏,卻和暖如春洛姑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背皮服。 一陣腳步聲響...
    開封第一講書人閱讀 33,869評論 1 274
  • 我被黑心中介騙來泰國打工楞艾, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人龄广。 一個月前我還...
    沈念sama閱讀 49,378評論 3 379
  • 正文 我出身青樓硫眯,卻偏偏與公主長得像,于是被迫代替她去往敵國和親择同。 傳聞我的和親對象是個殘疾皇子两入,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,937評論 2 361

推薦閱讀更多精彩內(nèi)容