Android之串口編程

閱讀時長:10分鐘java

原文地址:juejin.im/post/5bd96c…android

原文做者:YKamhgit

技術預備:Java基礎github

現在咱們生活中充滿了各類智能設備,方便了咱們的生活,這正是物聯網時代。若是咱們要開發智能設備,那麼Android串口編程是咱們應該必備的技能。編程

在投身到Android開發行業前,做者一直覺得Android開發就是單純的寫手機端應用。隨着接觸的項目愈來愈多,漸漸的開始接觸到了Android應用結合控制硬件設備的項目了,應用控制鎖、打印機、掃碼器等等,這正是要使用到安卓串口編程的知識。api

STEP1

安卓串口編程中使用到的是谷歌開源serialPort api數組

下載連接:安全

github.com/cepr/androi…bash

在GitHub上把所需資源下載下來以後就能夠按下圖的目錄結構放置資源app

請讀者注意框框內的東東,其中應爲使用到Google的原生so庫,SerialPort類的包名必定要是android_serialport_api,若是想修改這個包名,就須要從新生成對應的so庫。

還有就是SerialPort.java文件中的open()和close()方法雖然是紅色的但咱們不用理會,編譯是經過的。

STEP2

在項目gradle文件中的buildTypes節點下加上下面一句話

STEP3

編寫封裝串口工具類,主要分爲如下步驟來打開串口:

  1. 設置端口號、波特率

  2. 獲取打開的串口中的輸入輸出流,以便於串口數據的收發

  3. 打開讀取串口信息線程(接收串口返回信息不少時候都是須要等待的耗時操做,所以開啓線程去等待)

  4. 綁定串口返回監聽

  • path:端口號,必定要以這種格式編寫,針對硬件的不一樣可能會用到/dev/ttyS2或者/dev/ttyS1等等。

  • baudrate:波特率

  • serialPortStatus:串口打開標誌

  • data_:發送的串口數據

  • threadStatus:終止線程標誌位(這裏更應該加上Volatile修飾)

  • mSerialPort:谷歌提供的api

  • mInputStream:串口輸入流

  • mOutputStream:串口輸出流

/**
 * 
 * 打開串口     
 * @return  serialPort串口對象     
 */
public SerialPort openSerialPort()
{
    try {
        mSerialPort = new SerialPort(new File(path), baudrate, 0);
        this.serialPortStatus = true;
        threadStatus = false;
        //獲取打開的串口中的輸入輸出流,以便於串口數據的收發            
        mInputStream = mSerialPort.getInputStream();
        mOutputStream = mSerialPort.getOutputStream();
        new ReadThread().start();//開啓線程監控是否有數據的收發        
    } catch (IOException e){
        Log.e(TAG, "openSerialPort:打開串口異常:" + e.toString());
        return mSerialPort;
    }
    Log.d(TAG, "openSerialPort: 打開串口");
    return mSerialPort;
}
複製代碼

打開串口方法主要完成了使用Google API的構造方法傳入端口號和波特率,獲取輸入輸出流,打開監聽線程。

/**
 * 
 * 關閉串口     
 */
public void closeSerialPort()
{
    try {
        if (mInputStream != null) {
            mInputStream.close();
        }
        if (mOutputStream != null) {
            mOutputStream.close();
        }
        this.threadStatus = true;
        this.serialPortStatus = false;
        mSerialPort.close();
    } catch (IOException e){
        Log.e(TAG, "closeSerialPort: 關閉串口異常" + e.toString());
        return;
    }
    Log.d(TAG, "closeSerialPort: 串口關閉成功");
}
複製代碼

關閉串口方法裏主要完成了把輸入輸出流關閉,調用Google API關閉串口方法和使用標誌位方法安全關閉監聽線程。

public void sendSerialPort(String data)
{
    Log.d(TAG, "sendSerialPort: 發送數據" + data);
    try {
        byte[]
        sendData = data.getBytes("gb2312");
        this.data_ = new String(sendData);
        if (sendData.length > 0) {
            mOutputStream.write(sendData);
            mOutputStream.write('\n');
            mOutputStream.flush();
            Log.d(TAG, "sendSerialPort: 發送串口數據成功");
        }
    } catch (IOException e)
    {
        Log.e(TAG, "sendSerialPort: 串口發送數據失敗 " + e.toString());
    }
}
複製代碼

發送方法中,這個方法只是針對打印機操做實例來實現的,紅框中咱們要把發送的字符串換成gb2312的byte數組發送出去。

其實在串口通信中,全部的指令都要轉化爲byte數組發送出去的。你們能夠在做者的這個簡單工具類中加以改進,使其更加通用。

class ReadThread extends Thread {
    
    @Override 
    public void run() {
        super.run();            //判斷線程是否安全進行,更安全的結束線程            
        while (!threadStatus){
            Log.d(TAG, "進入線程run");
            byte[] buffer = new byte[64];
            int size;
            try {
                size = mInputStream.read(buffer);
                if (size > 0) {
                    Log.d(TAG, "run: 接收到數據大小:" + size);
                    onDataReceiveListener.onDataReceive(buffer, size);
                }
            } catch (IOException e){
                Log.e(TAG, "run: 數據讀取異常" + e.toString());
            }
        }
    }
}
複製代碼

監聽線程中重點在try代碼塊中,InputStream.read()方法是一個阻塞操做,可根據項目須要使用interrupt()方法快速關閉線程,無需使用標誌位等待到下一個循環才結束。

此外try代碼塊中還調用了onDataReceive()自定義接口的方法,用於返回線程監聽的數據。

public OnDataReceiveListener onDataReceiveListener = null;

public static interface OnDataReceiveListener
{
    void onDataReceive(byte[] buffer, int size);
}
public void setOnDataReceiveListener(OnDataReceiveListener listener)
{
    this.onDataReceiveListener = listener;
}
複製代碼

工具類中還有一個OnDataReceiveListener變量,用於在外部調用者設置監聽的接口。

注意這裏onDataReceive()方法中的參數 buffer,一樣的道理串口發送指令最終轉換爲byte數組發送,接收到的信息一樣也是byte數組類型,因此根據需求能夠將這個byte數組轉化爲字符串等等其餘。

下面提供byte數組轉換爲字符串的方法和字符串轉換成十六進制byte數組的方法。

完整代碼:

github.com/YKamh/Seria…

PS:Demo只是簡單實現了基本的串口編程功能,並無對細節優化。

結語

面臨物聯網時代的趨勢,android串口編程也是咱們所應該必備的。在以上知識點中,其中的的核心代碼依然是Java基礎,也體現出Java基礎的重要性。

在做者接觸結合硬件的項目的時候,心情是彷彿發現了新大陸,串口編程更是有趣,沒有開發純應用的枯燥。

但願你們一塊兒努力,一塊兒成長!

----- End -----

更多好文

請掃描下面二維碼

歡迎關注~

相關文章
相關標籤/搜索