安卓开发,串口收发,心跳检测,一写一出,回调结果

调用方式在最后一个代码片段噢

>>直接查看第六步

 

安卓开发,串口收发,心跳检测,一写一出,回调结果_第1张图片

 一.这里是串口基本控制类

package top.keepempty.serialportnormal;

import android.content.Context;
import android.os.Handler;
import android.util.Log;

import com.serialport.SerialPort;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import top.keepempty.sph.library.DataConversion;

/**
 * Create on 2019/9/5
 * author chtj
 */
public class SerialPortContrl {
    private static final String TAG = "SerialPortContrl";
    private Context context;//上下文
    private SerialPort port = null;//串口控制
    private OnComListener onComListener;//数据回调
    private SerialPortEntity serialPortEntity;
    private static boolean isOpen = false;//串口是否打开
    //定时检查串口是否正常
    private Handler handler = new Handler();
    //是否正在操作,一般存在两个状态
    //是否正在执行心跳包检测
    private boolean isHeartBeatOperation = false;
    //是否正在读写
    private boolean isWriteReadOperation = false;

    /**
     * 注册串口相关的数据监听
     *
     * @param onComListener
     */
    public void setOnComListener(OnComListener onComListener) {
        this.onComListener = onComListener;
    }

    //初始化时默认开启读取线程
    public SerialPortContrl(Context context, SerialPortEntity serialPortEntity) {
        this.serialPortEntity = serialPortEntity;
        this.context = context;
        openHeartBeatCheck();
    }

    //心跳检测
    //主要用于串口是否收发正常
    //如果要使用该方法 需要设置 SerialPortEntity中 heartBeatComm和heartBeatFlag的值
    public void openHeartBeatCheck() {
        if (serialPortEntity != null && serialPortEntity.getHeartBeatEntity().getHeartBeatComm() != null && serialPortEntity.getHeartBeatEntity().getHeartBeatFlag() != 0) {
            handler.postDelayed(heartBeatRunnable, 5000);
        }
    }

    Runnable heartBeatRunnable=new Runnable() {
        @Override
        public void run() {
            if (port != null) {
                try {
                    if (!isWriteReadOperation) {//判断是否在执行写读操作
                        writeData(serialPortEntity.getHeartBeatEntity().getHeartBeatComm());
                        //改变为正在执行
                        isHeartBeatOperation = true;
                        boolean isNormal = false;
                        while (true) {
                            //查询可以读取到的字节数量
                            //读取超时的检查 设置为3秒
                            //3秒内无响应 则退出
                            readSize = port.getInputStream().available();
                            //Log.e(TAG, "readSize=" + readSize );
                            if (readSize <= 0) {
                                //当前未检查到数据
                                waitTime += 200;
                                Thread.sleep(200);
                                isNormal = false;
                                if (waitTime >= serialPortEntity.getTimeOut()) {
                                    waitTime = 0;
                                    bytes = null;
                                    break;
                                }
                            } else {
                                //没有超时 获取到了数据
                                byte[]  temporaryComm=new byte[readSize];
                                port.getInputStream().read(temporaryComm);
                                Log.e(TAG,"心跳包返回数据:"+DataConversion.encodeHexString(temporaryComm));
                                isNormal = true;
                                break;
                            }
                        }
                        //Log.e(TAG, "串口能正常收发");
                        if (onComListener != null) {
                            onComListener.comStatus(isNormal);
                        }
                        isHeartBeatOperation = false;
                    }else{
                        Log.e(TAG,"当前正在进行写读操作,所以暂时不检查串口是否正常");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    Log.e(TAG, "heartBeatCheck: errMeg:" + e.getMessage());
                }
            }
            handler.postDelayed(this, serialPortEntity.getHeartBeatEntity().getDelayMillis());
        }
    };


    /**
     * 打开串口
     */
    public void openSerialPort() {
        //串口状态为关闭时 才能去执行开启
        if (!isOpen) {
            try {
                port = new SerialPort(new File(serialPortEntity.getCom()), serialPortEntity.getBaudrate(), 0);
                Log.e(TAG, "串口打开成功 com=" + serialPortEntity.getCom() + ",baudrate=" + serialPortEntity.getBaudrate());
                isOpen = true;
            } catch (IOException e) {
                e.printStackTrace();
                isOpen = false;
                Log.e(TAG, "串口访问失败!");
            } catch (SecurityException e) {
                e.printStackTrace();
                isOpen = false;
                Log.e(TAG, "请授予系统权限!");
            } catch (Exception e) {
                e.printStackTrace();
                isOpen = false;
                Log.e(TAG, "其他异常:" + e.getMessage());
            }
            if (onComListener != null) {
                if (isOpen) {
                    onComListener.isOpen(true);
                } else {
                    onComListener.isOpen(false);
                }
            }
        }
    }

    /**
     * 添加相关命令
     *
     * @param comm 单个命令
     * @param flag 传进来的flag 读取|写入|超时|写入完成等回调的时候可以标识为当前
     */
    public void setWriteRead(byte[] comm, int flag) {
        List commList = new ArrayList<>();
        commList.add(comm);
        this.setWriteRead(commList, flag);
    }

    /**
     * 添加相关命令
     *
     * @param commList 这次需要执行的命令集合
     * @param flag     传进来的flag 读取|写入|超时|写入完成等回调的时候可以标识为当前
     */
    public synchronized void setWriteRead(List commList, int flag) {
        while (isHeartBeatOperation){
            //如果正在操作心跳包检测
            //则暂时等待
        }
        if(port==null){
            if(onComListener!=null){
                onComListener.comStatus(false);
                return;
            }
        }
        isWriteReadOperation = true;//操作中
        if (commList != null && commList.size() > 0) {
            //Iterator 方便删除数据 而不影响下标
            Iterator it = commList.iterator();
            //用于标识3次机会是否用完 并且是否成功写入和读取
            //只有命令发送后在3次机会中成功至少一次的才能继续向下执行
            boolean isSuccessful = true;
            while (it.hasNext()) {
                // 注意:!serialPortEntity.getFlagFilterArray().contains(flag)
                //如果写入的命令存在一条以上时 执行完成一条后
                //如果添加进来的flag不管上一条是否执行失败 继续向下执行
                //否则只执行第一条就退出了
                if (isSuccessful == false && !serialPortEntity.getFlagFilterArray().contains(flag)) {
                    break;
                }
                byte[] nowData = it.next();
                int count = serialPortEntity.getRetriesCount();//数据写入之后的重试次数
                while (--count >= 0) {
                    //每次减去1
                    //然后去检查是否成功获取数据
                    //否则循环n次 继续
                    //还是失败的话则升级失败
                    try {
                        Thread.sleep(250);
                        writeData(nowData);
                        Log.e(TAG, "写入命令>>>:" + DataConversion.encodeHexString(nowData));
                        onComListener.writeCommand(nowData, flag);
                    } catch (Exception e) {
                        e.printStackTrace();
                        Log.e(TAG, "errMeg=" + e.getMessage());
                    } finally {
                        try {
                            if (readInputStreaData(flag)) {
                                it.remove();
                                isSuccessful = true;
                                break;
                            } else {
                                isSuccessful = false;
                                Log.e(TAG, "读取异常,继续重发,剩余重发送次数:" + count);
                                //如果剩余次数小于等于0
                                if (count <= 0) {
                                    if (serialPortEntity.getFlagFilterArray().contains(flag)) {
                                        it.remove();
                                    } else {
                                    }
                                    break;
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            Log.e(TAG, ">>" + e.getMessage());
                        } finally {
                            Log.e(TAG, "剩余写入的命令数量=" + commList.size());

                            if (commList == null || commList.size() == 0) {
                                onComListener.writeComplet(flag);
                            }
                        }
                    }
                }
            }
            //这里的判断 是防止可能命令只有一个
            if (!isSuccessful) {
                Log.e(TAG, "升级失败了~~~~");
            }
        }
        //操作结束
        isWriteReadOperation = false;
    }


    /**
     * 检查是否存在数据
     * 如果不存在数据就要做延时读取操作
     * 这里的延时时间为 {waitTime}
     *
     * @return 存在数据true  不存在数据false
     * @throws IOException
     * @throws InterruptedException
     */
    private boolean checkInputStreaData(int flag) throws IOException, InterruptedException {
        while (true) {
            //查询可以读取到的字节数量
            //读取超时的检查 设置为3秒
            //3秒内无响应 则退出
            readSize = port.getInputStream().available();
            //Log.e(TAG, "readSize=" + readSize );
            if (readSize <= 0) {
                //当前未检查到数据
                waitTime += 200;
                Thread.sleep(200);
                isExistData = false;
                if (waitTime >= serialPortEntity.getTimeOut()) {
                    waitTime = 0;
                    bytes = null;
                    //回调超时处理 通知UI
                    onComListener.isReadTimeOut(flag);
                    break;
                }
            } else {
                isExistData = true;
                break;
            }
        }
        return isExistData;
    }


    private int count = 0;//当前数据记录到哪一个位置
    private long datalength = -1;//接收到数据的总长度
    private int waitTime = 0;//线程等待时间
    private int readSize = 0;//目前数据流中的字节数量
    private int readNum = -1;//读取到的一个字节
    private byte[] bytes = null;//当前读取到数据
    private boolean isExistData = false;//是否读取到了数据
    byte[] dataLen = new byte[2];//记录命令中返回的两个字节长度

    /**
     * 读取数据流中的数据
     * 这里需要进行自定义
     * ①比如我这里存在两个数据头 0xAA和0x55  也就是对应(byte[0]下标count=0)和(byte[1]下标count=1)  那么就是要读两个字节出来判断
     * ②然后就是获取data长度 我这里用了两个字节表示长度 byte[3]和byte[4] 这个要看协议是否一致 不过一般是一个字节
     * ③获取到data长度后好需要加上一些固定长度 比如获取到的data为{0x12,0x13,0x14,0x15}长度为4 那么还需要加上另外数据位才能得到完整的总长度
     * 例如返回的数据:AA55000004A001A3017F
     * ①AA55为数据头 length=2
     * ②00 为地址 length=1
     * ③00 04 为data长度 length=2  这里为什么是04:因为我们的协议把④+⑤的长度算在了一起
     * ④A0 为指令 length=1
     * ⑤01 A3 01 为data内容 length=3
     * ⑥7F 为crc校验值 length=1
     * 注:
     * 所以除了data之外的其他固定长度为6
     * 再加上data的长度为4
     * 所以总长度产生的数据为AA 55 00 00 04 A0 01 A3 01 7F
     *
     */
    private boolean readInputStreaData(int flag) {
        try {
            while (true) {
                boolean isBreak = false;//是否需要中断
                bytes = new byte[256];
                if (checkInputStreaData(flag)) {
                    count = 0;
                    //读取缓存中的第一个字节 看是否与第一个数据头对应
                    readNum = port.getInputStream().read();
                    bytes[count] = (byte) readNum;
                    if (bytes[0] == -86) {//检查第一个数据头AA
                        count = 1;
                        if (checkInputStreaData(flag)) {
                            readNum = port.getInputStream().read();
                            bytes[count] = (byte) readNum;
                            if (bytes[1] == 85) {//检查第二个数据头 55
                                //Log.e(TAG, "两个数据头正确!");
                                while (true) {
                                    if (checkInputStreaData(flag)) {
                                        if ((readNum = port.getInputStream().read()) != -1) {
                                            count++;
                                            bytes[count] = (byte) readNum;
                                            //Log.e(TAG, "byte[count]=" + bytes[count] + ",count=" + count + ",datalength=" + datalength+",bytes="+DataConversion.encodeHexString(bytes));
                                            if (count == 3) {
                                                dataLen[0] = bytes[count];
                                            }
                                            if (count == 4) {
                                                //找到数据长度
                                                //长度包括--指令和数据
                                                //数据头1	数据头1	地址1	长度2	指令1	数据(...)	效验1
                                                //除了数据长度以外 其他的数据不变长度为6
                                                //所以这里得到了一个数据的总长度
                                                //用于去判断数据是否接收完成
                                                dataLen[1] = bytes[count];
                                                String dataLenHex = DataConversion.encodeHexString(dataLen);
                                                if (dataLenHex.length() % 2 == 1) {
                                                    dataLenHex = "0" + dataLenHex;//高位补0
                                                }
                                                datalength = DataConversion.hexToDec(dataLenHex) + 6;
                                                Log.e(TAG, "数据包长度=" + datalength);
                                            }
                                            //这里是判断指令位是否正确
                                            int msgNum = -1;
                                            if (count == 5) {//查看属于哪一种命令
                                                switch (bytes[5]) {
                                                    case -96://A0 检测升级
                                                        msgNum = 0;
                                                        break;
                                                    case -95://A1 进入升级
                                                        msgNum = 1;
                                                        break;
                                                    case -94://A2 数据写入
                                                        msgNum = 2;
                                                        break;
                                                    case -93://A3 数据写入成功
                                                        msgNum = 3;
                                                        break;
                                                    default://指令错误
                                                        msgNum = -1;
                                                        bytes = null;
                                                        count = 0;
                                                        //Log.e(TAG, "当前命令属于 现在需要将count清空,并且重置一些数据");
                                                        break;
                                                }
                                                //Log.e(TAG, "当前命令属于:" + message);
                                                if (msgNum == -1) {
                                                    break;//跳出循环 开始进行下一轮
                                                }
                                            }
                                            if (datalength == count + 1) {
                                                //Log.e(TAG, "数据校验完整");
                                                isBreak = true;
                                                //Log.e(TAG,"数据接收完成了噢,完整的数据为0:count"+count);
                                                break;
                                            }
                                        }
                                    } else {
                                        isBreak = true;
                                        break;
                                    }
                                }
                            }
                        } else {
                            break;
                        }
                    }
                } else {
                    break;
                }
                if (isBreak) {
                    //这里是由于数据读取完成 或者因为读取过程中超时
                    //所以需要退出
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            boolean isSuccessful = false;
            if (onComListener != null) {
                if (bytes != null && bytes.length > 0) {
                    //Log.e(TAG, "数据接收完成了噢,完整的数据为1:" + DataConversion.encodeHexString(bytes));
                    byte[] newbytes = new byte[(int) datalength];
                    System.arraycopy(bytes, 0, newbytes, 0, (int) datalength);
                    onComListener.readCommand(newbytes, flag);
                    isSuccessful = true;//正常情况下到这里都为true
                    //Log.e(TAG, "数据接收完成了噢,完整的数据为2:" + DataConversion.encodeHexString(newbytes));
                } else {
                    isSuccessful = false;
                    onComListener.readCommand(null, flag);
                }
            }
            return isSuccessful;
        }
    }

    /**
     * 写数据
     *
     * @param command
     */
    private synchronized void writeData(byte[] command) {
        port.write(command);
    }


    /**
     * 关闭串口和线程
     */
    public void closeSerialPort() {
        if (port != null) {
            port.close();
            port=null;
        }
        //取消心跳检测
        if (heartBeatRunnable != null) {
            Log.e(TAG, "心跳包周期检测已关闭");
            handler.removeCallbacks(heartBeatRunnable);
        }
        //设置为关闭状态
        isOpen = false;
        if (onComListener != null) {
            onComListener.isOpen(false);
        }
    }
}

二.这里是串口收发,串口状态回调接口

package top.keepempty.serialportnormal;

/**
 * Create on 2019/9/5
 * author chtj
 */
public interface OnComListener {
    //命令写入成功
    void writeCommand(byte[] comm, int flag);
    //获取到了数据流中的数据
    void readCommand(byte[] comm, int flag);
    //命令已全部写完
    void writeComplet(int flag);
    //执行超时
    void isReadTimeOut(int flag);
    //是否已经打开
    void isOpen(boolean isOpen);
    //得到串口状态 正常TRUE 异常FALSE
    void comStatus(boolean isNormal);
}

 三.这里是串口相关控制的实体类

package top.keepempty.serialportnormal;

import java.util.List;

/**
 * Create on 2019/9/18
 * author chtj
 */
public class SerialPortEntity {
    private String com;//串口号
    private int baudrate;//波特率
    private int timeOut;//读取超时时间
    private int retriesCount;//重试次数 默认为0次
    private HeartBeatEntity heartBeatEntity;//心跳包相关
    //如果写入的命令存在一条以上时 执行完成一条后
    //如果添加进来的flag不管上一条是否执行失败 继续向下执行
    //否则只执行第一条就退出了
    private List flagFilterArray;

    public SerialPortEntity() {
    }

    public SerialPortEntity(String com, int baudrate, int timeOut, int retriesCount, List flagFilterArray) {
        this.com = com;
        this.baudrate = baudrate;
        this.timeOut = timeOut;
        this.retriesCount = retriesCount;
        this.flagFilterArray = flagFilterArray;
    }

    public SerialPortEntity(String com, int baudrate, int timeOut, int retriesCount, HeartBeatEntity heartBeatEntity, List flagFilterArray) {
        this.com = com;
        this.baudrate = baudrate;
        this.timeOut = timeOut;
        this.retriesCount = retriesCount;
        this.heartBeatEntity = heartBeatEntity;
        this.flagFilterArray = flagFilterArray;
    }

    public String getCom() {
        return com;
    }

    public void setCom(String com) {
        this.com = com;
    }

    public int getBaudrate() {
        return baudrate;
    }

    public void setBaudrate(int baudrate) {
        this.baudrate = baudrate;
    }

    public int getTimeOut() {
        return timeOut;
    }

    public void setTimeOut(int timeOut) {
        this.timeOut = timeOut;
    }

    public int getRetriesCount() {
        return retriesCount;
    }

    public void setRetriesCount(int retriesCount) {
        this.retriesCount = retriesCount;
    }

    public HeartBeatEntity getHeartBeatEntity() {
        return heartBeatEntity;
    }

    public void setHeartBeatEntity(HeartBeatEntity heartBeatEntity) {
        this.heartBeatEntity = heartBeatEntity;
    }

    public List getFlagFilterArray() {
        return flagFilterArray;
    }

    public void setFlagFilterArray(List flagFilterArray) {
        this.flagFilterArray = flagFilterArray;
    }
}

四.这里是心跳包参数实体类

package top.keepempty.serialportnormal;

/**
 * Create on 2019/9/25
 * author chtj
 */
public class HeartBeatEntity {
    private byte[] heartBeatComm;//执行的心跳包命令
    private int heartBeatFlag;//执行心跳包的标志
    private int delayMillis;//多少周期执行一次心跳包检测毫秒

    public HeartBeatEntity(byte[] heartBeatComm, int heartBeatFlag, int delayMillis) {
        this.heartBeatComm = heartBeatComm;
        this.heartBeatFlag = heartBeatFlag;
        this.delayMillis = delayMillis;
    }

    public byte[] getHeartBeatComm() {
        return heartBeatComm;
    }

    public void setHeartBeatComm(byte[] heartBeatComm) {
        this.heartBeatComm = heartBeatComm;
    }

    public int getHeartBeatFlag() {
        return heartBeatFlag;
    }

    public void setHeartBeatFlag(int heartBeatFlag) {
        this.heartBeatFlag = heartBeatFlag;
    }

    public int getDelayMillis() {
        if(delayMillis==0){
            delayMillis=1*60*1000;//如果忘记设置心跳包的执行周期,将设置为1分钟
        }
        return delayMillis;
    }

    public void setDelayMillis(int delayMillis) {
        this.delayMillis = delayMillis;
    }
}

 五.这里为区分发送与写入回调的Flag标志

package top.keepempty.serialportnormal;

/**
 * Create on 2019/9/25
 * author chtj
 */
public class FlagManager {
    public static final int FLAG_HEARtBEAT=0x110;//心跳包定时检测标志
    public static final int FLAG_CHECK_UPDATE=0x111;//例如:这是检查更新的标志

}

 六.这里就是调用的方式

package top.keepempty.serialportnormal;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;

import com.serialport.SerialPortFinder;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import top.keepempty.R;
import top.keepempty.sph.library.DataConversion;
import top.keepempty.util.DataCehck;

public class SerialPortNormalAty extends AppCompatActivity implements View.OnClickListener {
    public static final String TAG = "SerialPortNormalAty";
    TextView tvResult;//返回的结果
    EditText etCommand;//命令
    Spinner sp_com,sp_burate;//串口列表,波特率列表
    SerialPortContrl serialPortContrl=null;//串口控制类
    List list_serialcom=null;//串口地址
    String[] arrays_burate;//波特率

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_serialport_normal);
        //初始化控件
        tvResult = findViewById(R.id.tvResult);
        tvResult.setMovementMethod(ScrollingMovementMethod.getInstance());
        etCommand = findViewById(R.id.etCommand);
        sp_com = findViewById(R.id.sp_com);
        sp_burate = findViewById(R.id.sp_burate);
        //获取所有串口地址
        SerialPortFinder mSerialPortFinder = new SerialPortFinder();
        String[] entryValues = mSerialPortFinder.getAllDevicesPath();
        list_serialcom= Arrays.asList(entryValues);
        //获取所有的波特率 可在R.array.burate 中手动添加需要的波特率
        arrays_burate = getResources().getStringArray(R.array.burate);
        //添加到适配器中显示
        ArrayAdapter arr_adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, list_serialcom);
        sp_com.setAdapter(arr_adapter);
    }


    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btn_close://关闭串口
                if(serialPortContrl!=null){
                    serialPortContrl.closeSerialPort();
                }
                break;
            case R.id.btn_init://初始化和开启串口
                //获得当前选择串口和波特率
                String com=sp_com.getSelectedItem().toString();
                int baudrate=Integer.parseInt(sp_burate.getSelectedItem().toString());
                //参数设置
                List flagFilterList=new ArrayList<>();
                flagFilterList.add(FlagManager.FLAG_CHECK_UPDATE);
                //①未开启心跳包
                //SerialPortEntity serialPortEntity=new SerialPortEntity(com,baudrate,6000,3,flagFilterList);

                //②心跳包参数设置
                HeartBeatEntity heartBeatEntity=new HeartBeatEntity(new byte[]{(byte) 0xAA, 0x55, 00, 0, 0x01, (byte) 0xA0, (byte) 0xBF},FlagManager.FLAG_HEARtBEAT,15*1000);
                SerialPortEntity serialPortEntity=new SerialPortEntity(com,baudrate,6000,3,heartBeatEntity,flagFilterList);
                //初始化数据
                serialPortContrl=new SerialPortContrl(this,serialPortEntity);
                //注册监听
                serialPortContrl.setOnComListener(new OnComListener() {

                    @Override
                    public void writeCommand(byte[] comm, int flag) {
                        String writeData="writeCommand>>> comm="+DataConversion.encodeHexString(comm)+",flag="+flag;
                        Log.e(TAG,writeData);
                        Message message=handler.obtainMessage();
                        message.obj=writeData;
                        handler.sendMessage(message);
                    }

                    @Override
                    public void readCommand(byte[] comm, int flag) {
                        String readData="readCommand>>> comm="+DataConversion.encodeHexString(comm)+",flag="+flag;
                        Log.e(TAG,readData);
                        Message message=handler.obtainMessage();
                        message.obj=readData;
                        handler.sendMessage(message);
                    }

                    @Override
                    public void writeComplet(int flag) {
                        String writeSuccessful="writeComplet>>> flag="+flag;
                        Log.e(TAG,writeSuccessful);
                        Message message=handler.obtainMessage();
                        message.obj=writeSuccessful;
                        handler.sendMessage(message);
                    }


                    @Override
                    public void isReadTimeOut(int flag) {
                        String readTimeOut="isReadTimeOut>>> flag="+flag;
                        Log.e(TAG,readTimeOut);
                        Message message=handler.obtainMessage();
                        message.obj=readTimeOut;
                        handler.sendMessage(message);
                    }

                    @Override
                    public void isOpen(boolean isOpen) {
                        String comStatus=isOpen?"isOpen>>>串口打开!":"isOpen>>>串口关闭";
                        Log.e(TAG,comStatus);
                        Message message=handler.obtainMessage();
                        message.obj=comStatus;
                        handler.sendMessage(message);
                    }

                    @Override
                    public void comStatus(boolean isNormal) {
                        String comStatus=isNormal?"comStatus>>>串口正常!":"comStatus>>>串口异常";
                        Log.e(TAG,comStatus);
                        Message message=handler.obtainMessage();
                        message.obj=comStatus;
                        handler.sendMessage(message);
                    }

                });
                //开启串口
                serialPortContrl.openSerialPort();
                break;
            case R.id.btn_test_send://发送命令
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        //这里只是一个示例
                        //这里时多个命令发送
                        /*List bytesList = new ArrayList<>();
                        for (int i = 0; i <=15; i++) {
                            byte[] bytes = new byte[]{(byte) 0xAA, 0x55, (byte) i, 0, 0x01, (byte) 0xA0};
                            byte crcNum = DataCehck.calcCrc8(bytes);//获得校验值
                            //复制到新的数组并把校验值填写到最后一位
                            byte[] newbytes = new byte[bytes.length + 1];
                            System.arraycopy(bytes, 0, newbytes, 0, 6);
                            newbytes[newbytes.length - 1] = crcNum;//填充校验值
                            //Log.e(TAG, "检测升级>>>计算校验值后得command[" + i + "]=" + DataConversion.encodeHexString(newbytes));
                            bytesList.add(newbytes);
                        }
                        if (bytesList.size() > 0) {
                            //传进去的flag 读取|写入|超时|写入完成等回调的时候可以标识为当前
                            serialPortContrl.setWriteRead(bytesList, FlagManager.FLAG_CHECK_UPDATE);
                        } else {
                            Log.e(TAG, "没有任何需要检测升级的 checkUpdate bytesList.size()=" + bytesList.size());
                        }*/
                        //单个命令发送
                        String hexComm=etCommand.getText().toString().trim();
                        byte[] comm=DataConversion.decodeHexString(hexComm);
                        serialPortContrl.setWriteRead(comm, FlagManager.FLAG_CHECK_UPDATE);
                    }
                }).start();
                break;
            case R.id.btn_clear://清除结果
                tvResult.setText("");
                break;
        }
    }
    Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            tvResult.append("\n\r"+msg.obj.toString());
        }
    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(serialPortContrl!=null){
            serialPortContrl.closeSerialPort();
        }
    }
}

 

 

你可能感兴趣的:(android串口,串口工具类,物联网串口)