欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android studio 串口通信(动态获取串口)

程序员文章站 2022-03-03 11:46:18
串口类用的是标准的官方标准的类,可自行下载。界面效果图布局文件

第一次写博客,不知道说些什么,给大家拜个早年吧。
谷歌开源串口类serialPort-api
源码下载:冲冲冲
没有积分点赞留言发邮箱^^

界面效果图

Android studio 串口通信(动态获取串口)

布局文件

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/txt_comrecv"
        android:layout_width="0dp"
        android:layout_height="600dp"
        android:background="@android:drawable/editbox_background_normal"
        android:scrollbars="vertical"
        android:singleLine="false"
        android:textSize="24sp"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/Ra_sidebar"
        app:layout_constraintTop_toTopOf="parent" />

    <LinearLayout
        android:id="@+id/la_center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/txt_comrecv">

        <Spinner
            android:id="@+id/Spin_Serial_port"
            android:layout_width="100dp"
            android:layout_height="50dp"
            android:layout_marginStart="20dp"
            android:background="#B5BDBC"
            android:dropDownWidth="150dp"
            android:spinnerMode="dropdown"
            android:theme="@style/spinnerHead"
            android:visibility="visible" />

        <Spinner
            android:id="@+id/Spin_Baudrate"
            android:layout_width="100dp"
            android:layout_height="50dp"
            android:layout_marginStart="20dp"
            android:background="#B5BDBC"
            android:dropDownWidth="150dp"
            android:entries="@array/Baud_rate"
            android:spinnerMode="dropdown"
            android:theme="@style/spinnerHead"
            android:visibility="visible" />

        <Button
            android:id="@+id/btn_open"
            android:layout_width="wrap_content"
            android:layout_height="70dp"
            android:layout_marginStart="20dp"
            android:text="打开串口"
            android:textSize="20dp"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />


        <Button
            android:id="@+id/btn_Send_out"
            android:layout_width="100sp"
            android:layout_height="70dp"
            android:layout_marginStart="20dp"
            android:layout_alignParentBottom="true"
            android:text="发送"
            android:textSize="20dp" />


        <Button
            android:id="@+id/btn_close"
            android:layout_width="wrap_content"
            android:layout_height="70dp"
            android:layout_marginStart="20dp"
            android:text="关闭串口"
            android:textSize="20dp"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <CheckBox
            android:id="@+id/Cbx_automatic_Send_out"
            android:layout_width="wrap_content"
            android:layout_height="70dp"
            android:layout_marginStart="20dp"
            android:checked="false"
            android:text="自动发送"
            android:textSize="20dp"

            />

        <RadioGroup
            android:id="@+id/ra_style"
            android:layout_width="wrap_content"
            android:layout_marginStart="20dp"
            android:layout_height="wrap_content">

            <RadioButton
                android:id="@+id/Rdi_btn_Txt"
                android:layout_width="100sp"
                android:layout_height="wrap_content"
                android:checked="true"
                android:text="Txt"
                android:textSize="20dp"
                />

            <RadioButton
                android:id="@+id/Rdi_btn_Hex"
                android:layout_width="100sp"
                android:layout_height="wrap_content"
                android:layout_below="@+id/Rdi_btn_Txt"
                android:text="Hex"
                android:textSize="20dp" />

        </RadioGroup>


        <Button
            android:id="@+id/btn_clean"
            android:layout_width="100sp"
            android:layout_height="70dp"
            android:layout_marginStart="20dp"
            android:layout_below="@+id/ra_style"
            android:text="清除"
            android:textSize="20dp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/txt_log"
            />


    </LinearLayout>


    <EditText
        android:id="@+id/Et_txt_input"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@android:drawable/editbox_background_normal"
        android:gravity="left"
        android:text="COMA"
        android:textSize="20sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/Ra_sidebar"
        app:layout_constraintTop_toBottomOf="@+id/la_center" />


    <RelativeLayout
        android:id="@+id/Ra_sidebar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent">



    </RelativeLayout>


</androidx.constraintlayout.widget.ConstraintLayout>

获取Android设备dev目录下的tty

    //获取串口
    static String[] getSerial_Ports_name() {
        List<String> Serial_Ports_number = new ArrayList<String>();
        String[] type = null;
        File file = new File("/dev/");
        File[] fs = file.listFiles();
        for (File f : fs) {
            if (f.getName().contains("tty")) {
                Serial_Ports_number.add(f.getName());
            }
        }
        type = Serial_Ports_number.toArray(new String[Serial_Ports_number.size()]);
        return type;
    }

Spinner选择串口与波特率

 //选择串口
        Spin_Serial_port = (Spinner) findViewById(R.id.Spin_Serial_port);
        ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,R.layout.my_spinner_item);
        String[] itemNames = getSerial_Ports_name();
        Arrays.sort(itemNames);//从大往小排序
        for (int i = 0; i < itemNames.length; i++) {
            dataAdapter.add(itemNames[i]);
        }
        Spin_Serial_port.setAdapter(dataAdapter);
        Spin_Serial_port.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                String text = Spin_Serial_port.getItemAtPosition(position).toString();
                Serial_port_name = text;
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });


        //选择波特率
        final Resources res = getResources();
        String[] city = res.getStringArray(R.array.Baud_rate);
        Spin_Baudrate = (Spinner) findViewById(R.id.Spin_Baudrate);
        final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.my_spinner_item, city);
        Spin_Baudrate.setAdapter(adapter);
        Spin_Baudrate.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                String text = Spin_Baudrate.getItemAtPosition(position).toString();
                Spin_Baudrate_num = text;
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });
        Spin_Baudrate.setSelection(1);  //从第一位开始算

RadioGroup切换Hex或Txt发送模式

  //选择发送模式(Txt/Hex)
        RadioGroup ra_style = (RadioGroup) findViewById(R.id.ra_style);
        ra_style.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                //isChecked 默认为true
                if (Rdi_btn_Txt.isChecked()) {
                    Et_txt_input.setText("COMA");
                    Log.e("发送Txt消息", "ischecked :" + Rdi_btn_Txt.isChecked());
                    sendtype = 0;
                } else {
                    sendtype = 1;
                    //限制Hex模式发送字符
                    Et_txt_input.setText("AA");
                    Log.e("发送Hex消息", "ischecked :" + Rdi_btn_Txt.isChecked());
                    Rdi_btn_Hex = (RadioButton) findViewById(R.id.Rdi_btn_Hex);
                    Rdi_btn_Hex.setOnClickListener(new OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            Et_txt_input = (EditText) findViewById(R.id.Et_txt_input);
                            Et_txt_input.addTextChangedListener(new TextWatcher() {
                                @Override
                                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                                }

                                @Override
                                public void onTextChanged(CharSequence s, int start, int before, int count) {
                                    String limit = "";
                                    String regEx = "[^a-fA-F0-9]";
                                    Pattern p = Pattern.compile(regEx);
                                    Matcher m = p.matcher(limit);
                                    String str = m.replaceAll("").trim();
                                    if (!limit.equals(str)) {
                                        Et_txt_input.setText(str);
                                        Et_txt_input.setSelection(str.length());
                                    }
                                }

                                @Override
                                public void afterTextChanged(Editable s) {
                                }
                            });
                        }
                    });
                }
            }
        });

CheckBox勾选自动发送

        //选择自动发送
        Cbx_automatic_Send_out.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, final boolean isChecked) {
                //未打开串口并勾选自动发送时
                if (mySerialOperator.isOpen() == false) {
                    Log.e("请打开串口", "xxxxxxxxx");
                    String str = "请打开串口";
                    Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
                    return;
                }
                //勾选自动发送
                if (Cbx_automatic_Send_out.isChecked()) {
                    Log.e("isChecked", "======\r" + isChecked);
                    Cbx_automatic_Send_out.setOnClickListener(new OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            new Thread(new Runnable() {
                                volatile boolean exit = false;

                                @Override
                                public void run() {
                                    while (!exit) {
                                        //exit = true;
                                        if (!exit && mySerialOperator != null && mySerialOperator.isOpen()) {
                                            Log.e("开启自动发送", "");
                                            SimpleDateFormat dateformat = new SimpleDateFormat("[HH:mm:ss]");
                                            final String str1 = dateformat.format(System.currentTimeMillis());
                                            String txtToSend = Et_txt_input.getText().toString();
                                            if( sendtype == 0){
                                                aa += txtToSend.getBytes().length;
                                                //txt_log.setText(String.format("发%d收%d",aa,ss));
                                                mySerialOperator.send( txtToSend.getBytes() );
                                            }
                                            else{
                                                txtToSend.replace("\r", "" );
                                                txtToSend.replace("\n", "" );
                                                txtToSend.replace(" ", "" );

                                                if( txtToSend.length()%2 != 0)
                                                    txtToSend += "0";

                                                mySerialOperator.send( hexStringToBytes( txtToSend ) );
                                            }
                                            Scroll_to_bottom();
                                            //开启自动发送 500ms 刷新一次
                                            try {
                                                Thread.sleep(500);
                                            } catch (InterruptedException e) {
                                                e.printStackTrace();
                                            }
                                            //关闭自动发送
                                            if (!Cbx_automatic_Send_out.isChecked()) {
                                                Log.e("关闭自动发送", "close automatic send");
                                                break;
                                            }
                                        }

                                    }
                                }
                            }).start();
                        }
                    });
                }
            }
        });

输出消息定位在底部

    //输出信息定位在底部
    void Scroll_to_bottom() {
        int offset = txt_comrecv.getLineCount() * txt_comrecv.getLineHeight();
        if (offset > txt_comrecv.getHeight()) {
            txt_comrecv.scrollTo(0, offset - txt_comrecv.getHeight());
        }
    }

全部代码


import java.io.File;


import java.io.IOException;

import java.lang.reflect.Array;
import java.text.SimpleDateFormat;
import java.util.ArrayList;

import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Editable;

import android.text.TextWatcher;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.WindowManager;
import android.widget.*;
import android.app.Activity;

import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity implements OnClickListener {

    Button btn_open;
    Button btn_clean;
    Button btn_close;
    Button btn_Send_out;
    TextView txt_comrecv;
    TextView txt_log;
    EditText Et_txt_input;
    Spinner Spin_Serial_port;
    Spinner Spin_Baudrate;
    CheckBox Cbx_automatic_Send_out;
    RadioButton Rdi_btn_Txt;
    RadioButton Rdi_btn_Hex;

    private SerialOperator mySerialOperator;


    String Spin_Baudrate_num;
    String Serial_port_name;
    int sendtype = 0;//发送类型 0 = 文本 1 = hex


    //获取串口
    static String[] getSerial_Ports_name() {
        List<String> Serial_Ports_number = new ArrayList<String>();
        String[] type = null;
        File file = new File("/dev/");
        File[] fs = file.listFiles();
        for (File f : fs) {
            if (f.getName().contains("tty")) {
                Serial_Ports_number.add(f.getName());
            }
        }
        type = Serial_Ports_number.toArray(new String[Serial_Ports_number.size()]);
        return type;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Cbx_automatic_Send_out = (CheckBox) findViewById(R.id.Cbx_automatic_Send_out);
        btn_Send_out = (Button) findViewById(R.id.btn_Send_out);
        btn_open = (Button) findViewById(R.id.btn_open);
        btn_clean = (Button) findViewById(R.id.btn_clean);
        btn_close = (Button) findViewById(R.id.btn_close);
        Et_txt_input = (EditText) findViewById(R.id.Et_txt_input);
        Rdi_btn_Txt = (RadioButton) findViewById(R.id.Rdi_btn_Txt);
        Rdi_btn_Hex = (RadioButton) findViewById(R.id.Rdi_btn_Hex);
        txt_log = (TextView) findViewById(R.id.txt_log);

        Cbx_automatic_Send_out.setOnClickListener(this);
        btn_Send_out.setOnClickListener(this);
        btn_open.setOnClickListener(this);
        btn_clean.setOnClickListener(this);
        btn_close.setOnClickListener(this);
        Rdi_btn_Txt.setOnClickListener(this);
        Rdi_btn_Hex.setOnClickListener(this);

        //侧边滑动条
        txt_comrecv = (TextView) this.findViewById(R.id.txt_comrecv);
        txt_comrecv.setMovementMethod(ScrollingMovementMethod.getInstance());


        //清除显示文本内容
        txt_comrecv = (TextView) findViewById(R.id.txt_comrecv);
        btn_clean.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                txt_comrecv.setText(null);

                ss = 0;
                aa = 0;
                txt_log.setText(String.format("发%d收%d",aa,ss));
            }
        });

        //选择串口
        Spin_Serial_port = (Spinner) findViewById(R.id.Spin_Serial_port);
        ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,R.layout.my_spinner_item);
        String[] itemNames = getSerial_Ports_name();
        Arrays.sort(itemNames);//从大往小排序
        for (int i = 0; i < itemNames.length; i++) {
            dataAdapter.add(itemNames[i]);
        }
        Spin_Serial_port.setAdapter(dataAdapter);
        Spin_Serial_port.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                String text = Spin_Serial_port.getItemAtPosition(position).toString();
                Serial_port_name = text;
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });


        //选择波特率
        final Resources res = getResources();
        String[] city = res.getStringArray(R.array.Baud_rate);
        Spin_Baudrate = (Spinner) findViewById(R.id.Spin_Baudrate);
        final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.my_spinner_item, city);
        Spin_Baudrate.setAdapter(adapter);
        Spin_Baudrate.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                String text = Spin_Baudrate.getItemAtPosition(position).toString();
                Spin_Baudrate_num = text;
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });
        Spin_Baudrate.setSelection(1);  //从第一位开始算

        mySerialOperator = new SerialOperator();

        //选择发送模式(Txt/Hex)
        RadioGroup ra_style = (RadioGroup) findViewById(R.id.ra_style);
        ra_style.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                //isChecked 默认为true
                if (Rdi_btn_Txt.isChecked()) {
                    Et_txt_input.setText("COMA");
                    Log.e("发送Txt消息", "ischecked :" + Rdi_btn_Txt.isChecked());
                    sendtype = 0;
                } else {
                    sendtype = 1;
                    //限制Hex模式发送字符
                    Et_txt_input.setText("AA");
                    Log.e("发送Hex消息", "ischecked :" + Rdi_btn_Txt.isChecked());
                    Rdi_btn_Hex = (RadioButton) findViewById(R.id.Rdi_btn_Hex);
                    Rdi_btn_Hex.setOnClickListener(new OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            Et_txt_input = (EditText) findViewById(R.id.Et_txt_input);
                            Et_txt_input.addTextChangedListener(new TextWatcher() {
                                @Override
                                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                                }

                                @Override
                                public void onTextChanged(CharSequence s, int start, int before, int count) {
                                    String limit = "";
                                    String regEx = "[^a-fA-F0-9]";
                                    Pattern p = Pattern.compile(regEx);
                                    Matcher m = p.matcher(limit);
                                    String str = m.replaceAll("").trim();
                                    if (!limit.equals(str)) {
                                        Et_txt_input.setText(str);
                                        Et_txt_input.setSelection(str.length());
                                    }
                                }

                                @Override
                                public void afterTextChanged(Editable s) {
                                }
                            });
                        }
                    });
                }
            }
        });

        //选择自动发送
        Cbx_automatic_Send_out.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, final boolean isChecked) {
                //未打开串口并勾选自动发送时
                if (mySerialOperator.isOpen() == false) {
                    Log.e("请打开串口", "xxxxxxxxx");
                    String str = "请打开串口";
                    Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
                    return;
                }
                //勾选自动发送
                if (Cbx_automatic_Send_out.isChecked()) {
                    Log.e("isChecked", "======\r" + isChecked);
                    Cbx_automatic_Send_out.setOnClickListener(new OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            new Thread(new Runnable() {
                                volatile boolean exit = false;

                                @Override
                                public void run() {
                                    while (!exit) {
                                        //exit = true;
                                        if (!exit && mySerialOperator != null && mySerialOperator.isOpen()) {
                                            Log.e("开启自动发送", "");
                                            SimpleDateFormat dateformat = new SimpleDateFormat("[HH:mm:ss]");
                                            final String str1 = dateformat.format(System.currentTimeMillis());
                                            String txtToSend = Et_txt_input.getText().toString();
                                            if( sendtype == 0){
                                                aa += txtToSend.getBytes().length;
                                                //txt_log.setText(String.format("发%d收%d",aa,ss));
                                                mySerialOperator.send( txtToSend.getBytes() );
                                            }
                                            else{
                                                txtToSend.replace("\r", "" );
                                                txtToSend.replace("\n", "" );
                                                txtToSend.replace(" ", "" );

                                                if( txtToSend.length()%2 != 0)
                                                    txtToSend += "0";

                                                mySerialOperator.send( hexStringToBytes( txtToSend ) );
                                            }
                                            Scroll_to_bottom();
                                            //开启自动发送 500ms 刷新一次
                                            try {
                                                Thread.sleep(500);
                                            } catch (InterruptedException e) {
                                                e.printStackTrace();
                                            }
                                            //关闭自动发送
                                            if (!Cbx_automatic_Send_out.isChecked()) {
                                                Log.e("关闭自动发送", "close automatic send");
                                                break;
                                            }
                                        }

                                    }
                                }
                            }).start();
                        }
                    });
                }
            }
        });
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (mySerialOperator != null) {
            mySerialOperator.stopSend();
            mySerialOperator.close();
            mySerialOperator = null;
        }
    }

    public static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));

        }
        return d;
    }
    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }


    //输出信息定位在底部
    void Scroll_to_bottom() {
        int offset = txt_comrecv.getLineCount() * txt_comrecv.getLineHeight();
        if (offset > txt_comrecv.getHeight()) {
            txt_comrecv.scrollTo(0, offset - txt_comrecv.getHeight());
        }
    }

    long ss;
    long aa;

    Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 0:
                    //拿到数据,完成主界面更新
//              String data = (String)msg.obj;
                    byte[] bytes = (byte[]) msg.obj;
                    int arg1 = msg.arg1;
                    String strRecv ;
                    if(sendtype == 0){
                        strRecv = new String(bytes,0,arg1);
                    }else{
                        strRecv = bytes2HexString(bytes,arg1);
                        StringBuilder stringBuilder2=new StringBuilder(strRecv);

                        for(int i = strRecv.length(); i>0; i--){
                            if(i%2 ==0 )
                                stringBuilder2.insert(i," ");
                        }

                        strRecv = stringBuilder2.toString();
                    }

                    SimpleDateFormat dateformat = new SimpleDateFormat("[HH:mm:ss]");
                    final String Send = dateformat.format(System.currentTimeMillis());


//              txt_recv.setText(data);

                    StringBuilder sMsg = new StringBuilder();
                    sMsg.append("\r\n");
                    sMsg.append(Send+ strRecv);

                    txt_comrecv.append(sMsg);
                    ss += arg1;
                    txt_log.setText(String.format("发%d收%d",aa,ss));
                    //txt_log.setText(Long.toString(ss));
                    Scroll_to_bottom();//滚动到底部

                    break;
                default:
                    break;
            }
        }

    };

    public static String bytes2HexString(byte[] b, int len) {
        String ret = "";
        for (int i = 0; i < len; i++) {
            String hex = Integer.toHexString(b[ i ] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            ret += hex.toUpperCase();
        }
        return ret;
    }
    @Override
    public void onClick(View v) {

        //打开串口 发送消息 关闭串口
        switch (v.getId()) {

            //打开串口
            case R.id.btn_open:

                if (mySerialOperator != null) {
                    mySerialOperator.close();
                    mySerialOperator = null;
                }
                mySerialOperator = new SerialOperator();
                mySerialOperator.setBaudRate(Spin_Baudrate_num);
                mySerialOperator.setPort("/dev/" + Serial_port_name);
                mySerialOperator.setHandler(mHandler);
                Log.e("打开串口", "open\r");

                Toast.makeText(MainActivity.this, "打开串口成功", Toast.LENGTH_SHORT).show();
                try {
                    mySerialOperator.open();
                } catch (SecurityException | IOException e) {
                    e.printStackTrace();
                }
                break;

            //发送数据
            case R.id.btn_Send_out:

                if (mySerialOperator == null || mySerialOperator.isOpen() == false) {
                    String str = "请先打开串口";
                    Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
                    return;
                }

                String txtToSend = Et_txt_input.getText().toString();
                if( txtToSend == null || txtToSend.isEmpty() )
                {
                    Toast.makeText(MainActivity.this, "输入内容再点发送", Toast.LENGTH_SHORT).show();
                    return;
                }

                if( sendtype == 0){
                    aa += txtToSend.getBytes().length;
                    txt_log.setText(String.format("发%d收%d",aa,ss));
                    mySerialOperator.send( txtToSend.getBytes() );
                }
                else{
                    txtToSend.replace("\r", "" );
                    txtToSend.replace("\n", "" );
                    txtToSend.replace(" ", "" );

                    if( txtToSend.length()%2 != 0)
                        txtToSend += "0";
                    aa += hexStringToBytes(txtToSend).length;
                    txt_log.setText(String.format("发%d收%d",aa,ss));
                    mySerialOperator.send( hexStringToBytes( txtToSend ) );

                }
                break;

            //关闭串口
            case R.id.btn_close:
                String close = "关闭串口";
                if (mySerialOperator != null) {
                    mySerialOperator.stopSend();
                    mySerialOperator.close();
                    mySerialOperator = null;
                    Log.e("关闭串口", "close coms");
                    Toast.makeText(MainActivity.this, close, Toast.LENGTH_SHORT).show();
                }
                break;
            default:
                break;
        }
    }
}

两个工具类

package com.idean.tools;

/**
 * @author Tim
 * @����D�Q����
 */
public class ConvertedType {
	//-------------------------------------------------------
	// �ж�������ż����λ���㣬���һλ��1��Ϊ������Ϊ0��ż��
    /**
     * @param num
     * @return
     */
    static public int isOdd(int num)
	{
		return num & 0x1;
	}
    //-------------------------------------------------------
    static public int HexToInt(String inHex)//Hex�ַ���תint
    {
    	return Integer.parseInt(inHex, 16);
    }
    //-------------------------------------------------------
    static public byte HexToByte(String inHex)//Hex�ַ���תbyte
    {

    	return (byte)Integer.parseInt(inHex,16);
    }
    //-------------------------------------------------------
    static public String Byte2Hex(Byte inByte)//1�ֽ�ת2��Hex�ַ�
    {
    	return String.format("%02x", inByte).toUpperCase();
    }
    //-------------------------------------------------------
	static public String ByteArrToHex(byte[] inBytArr)//�ֽ�����תתhex�ַ���
	{
		StringBuilder strBuilder=new StringBuilder();
		int j=inBytArr.length;
		for (int i = 0; i < j; i++)
		{
			strBuilder.append(Byte2Hex(inBytArr[i]));
			strBuilder.append(" ");
		}
		return strBuilder.toString(); 
	}
  //-------------------------------------------------------
    static public String ByteArrToHex(byte[] inBytArr,int offset,int byteCount)//�ֽ�����תתhex�ַ�������ѡ����
	{
    	StringBuilder strBuilder=new StringBuilder();
		int j=byteCount;
		for (int i = offset; i < j; i++)
		{
			strBuilder.append(Byte2Hex(inBytArr[i]));
		}
		return strBuilder.toString();
	}
	//-------------------------------------------------------
	//תhex�ַ���ת�ֽ�����
    static public byte[] HexToByteArr(String inHex)//hex�ַ���ת�ֽ�����
	{
		int hexlen = inHex.length();
		byte[] result;
		if (isOdd(hexlen)==1)
		{//����
			hexlen++;
			result = new byte[(hexlen/2)];
			inHex="0"+inHex;
		}else {//ż��
			result = new byte[(hexlen/2)];
		}
	    int j=0;
		for (int i = 0; i < hexlen; i+=2)
		{
			result[j]=HexToByte(inHex.substring(i,i+2).trim());
			j++;
		}
	    return result; 
	}
}

package com.idean.tools;
import android.util.Log;

public class Debug {

	public boolean isShow = false;
	public String showLog;
	public static final boolean DEBUG_VESION = true;
	public static final boolean RELEASE_VESION = false;
	public static final int ERROR = 0;
	public static final int WARN = 1;
	public static final int INFO = 2;
	public static final int DEBUG = 3; 
	public static final int VERBOSE = 4;
	public Debug() {
	}
	
	/**
	 * @param isShow
	 * @param showLog
	 */
	public Debug(boolean isShow, String showLog) {
		this.isShow = isShow;
		this.showLog = showLog;
	}

	public boolean isShow() {
		return isShow;
	}
	public void setShow(boolean isShow) {
		this.isShow = isShow;
	}
	public String getShowLog() {
		return showLog;
	}
	public void setShowLog(String showLog) {
		this.showLog = showLog;
	}

	
	public static void showLog(boolean isRelaseVersion,String tag,String log,int level){
		
		if (isRelaseVersion) {
			switch (level) {
			case ERROR:
				Log.e(tag, log);
				break;
			case WARN:
				Log.w(tag, log);
				break;
			case INFO:
				Log.i(tag, log);
				break;
			case DEBUG:
				Log.d(tag, log);
				break;
			default:
				Log.v(tag, log);
				break;
			}
		}
	}
	
	
}

注意

未做打开串口失败的处理,每次点击打开串口都会弹出一个Toast,实际上串口并未打开。

本文地址:https://blog.csdn.net/weixin_45401264/article/details/107876116