天天看点

安卓开发中如何使用串口进行通信

写在前面

  • 很久不写博客,然后最近因为需要用到安卓板子上的串口,然后看了好多文章,发现好多文章都是复制来复制去的,一点逻辑都没有,实在受不了噢,无奈之下,只能自己做个笔记了。

准备工作

  • 安卓开发工具,Android Studio 我这里的版本是3.6.3
  • 安卓SDK 我选择了API29
  • 安卓Builde Tools 选择了29.0.3
  • NDK选择了:android-ndk-r17c
  • 对于环境这块,如果后续要更新这篇文章的话,到时候会同意整一个环境搭建篇。毕竟我现在也是半桶水,半路出家搞安卓平台相关的。

搭建工程

  • 老样子,在安卓Studio界面的工具栏中选择File->New->New Project
    安卓开发中如何使用串口进行通信
  • 创建的文件名称,包类型之类的信息如下,最后选择finish
    安卓开发中如何使用串口进行通信

环境配置

  • 在app/build.gradle文件配置中的dependencies,加上
安卓开发中如何使用串口进行通信
  • 在gradle/build.gradle中添加
安卓开发中如何使用串口进行通信
  • 工程编译设置,这里按照默认的方式设置就可以.
安卓开发中如何使用串口进行通信
  • 在根目录下的local.properties文件中,添加ndk路径,这里的ndk上网搜一下,很容易下载到的
ndk.dir= 你们ndk的路径
           
安卓开发中如何使用串口进行通信
  • 最后点击Android Studio 工具栏上的Run->run app,编译运行。

应用程序

  • 在activity文件中,添加一个按键控件,并将id取为button2
    安卓开发中如何使用串口进行通信
  • 代码方面,创建2个class,具体代码如下
安卓开发中如何使用串口进行通信
  • MainActivity代码如下
package com.kuensan.uart;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    private rs485Thread Rs485nThread;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btn = (Button) this.findViewById(R.id.button2);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //TODO Auto-generated method stub
                setTitle("button1 被用户点击了");
                Log.i("widgetDemo", "button2 被用户点击了。");
                System.out.println("被用户点击了 111");

                startGuestScreen();
            }
        });
    }

    private void startGuestScreen() {
        if (Rs485nThread == null) {
            Rs485nThread = new rs485Thread("/dev/ttyHSL2", 115200);
        }
        if (!Rs485nThread.isAlive()) {
            Rs485nThread.start();
        }

        Rs485nThread.sendRs485Data();
    }

}

           
  • rs485Thread代码如下
package com.kuensan.uart;

import android.util.Log;
import android.serialport.SerialPort;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.security.InvalidParameterException;
import java.util.Arrays;


public class rs485Thread extends Thread {

    protected SerialPort mSerialPort;
    protected OutputStream mOutputStream;
    private InputStream mInputStream;


    public rs485Thread(String deviceName, int baudrate) {
        try {
            closeSerialPort();
            if (mSerialPort == null) {
                mOutputStream = mSerialPort.getOutputStream();
                mInputStream = mSerialPort.getInputStream();
                mSerialPort = getSerialPort(deviceName, baudrate);
            }
        } catch (InvalidParameterException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    /**
     * @Title: closeSerialPort
     * @Description: 关闭串口
     * @param:
     * @return: void
     */
    private void closeSerialPort() {
        if (mSerialPort != null) {
            mSerialPort.close();
            mSerialPort = null;
        }
        if (mOutputStream != null) {
            try {
                mOutputStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        if (mInputStream != null) {
            try {
                mInputStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    /**
     * @Title: getSerialPort
     * @Description: 打开串口设备
     * @param: @param deviceName 串口设备名
     * @param: @return 返回串口类实例对象
     * @param: @throws SecurityException
     * @param: @throws IOException
     * @param: @throws InvalidParameterException
     * @return: SerialPort
     */
    private SerialPort getSerialPort(String deviceName, int baudrate)
            throws SecurityException, IOException, InvalidParameterException {
        if (mSerialPort == null) {
            /* Open the serial port */
            mSerialPort = new SerialPort(new File(deviceName), baudrate);
        }
        return mSerialPort;
    }

    /**
     * @Title: serialPortSendData
     * @Description: 发送数据
     * @param: @param data 要发送的数据的数组
     * @param: @return
     * @return: boolean 成功true 失败false
     */
    public boolean serialPortSendData(byte[] data) {
        if (mOutputStream == null) {
            return false;
        }
        try {
            Log.d("dove", "发送的数据是:" + Arrays.toString(data));
            mOutputStream.write(data);
            mOutputStream.flush();
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    public void sendRs485Data() {

        byte[] bData = new byte[8];
        int iLen = 0;

        bData[iLen++] = (byte) 0xAA;//开头
        bData[iLen++] = (byte) 0x11;//发送字的标记

        bData[iLen++] = (byte) 0x22;

        bData[iLen++] = (byte) 0x33;
        bData[iLen++] = (byte) 0x44;

        bData[iLen++] = (byte) 0x55;
        bData[iLen++] = (byte) 0x66;

        bData[iLen++] = (byte) 0;

        serialPortSendData(bData);

    }
}

           
  • 最后进行编译,安装到目标板上,这里我根据硬件串口位置,选择了 dev/ttyHSL2设备,波特率设置为115200

验证

  • 板子现在不在手上,所以先不进行验证了,待板子回来的时候再验证。