Android studio 串口通信(动态获取串口)
16lz
2021-01-23
第一次写博客,不知道说些什么,给大家拜个早年吧。
谷歌开源串口类serialPort-api
源码下载:gogogo
界面效果图
布局文件
<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,实际上串口并未打开。
更多相关文章
- Android——消息机制
- Android Handler 线程消息机制
- Android串口通信:抱歉,学会它真的可以为所欲为
- 【Android】源码分析 - Handler消息机制再梳理
- android 串口编程
- Android应用程序键盘(Keyboard)消息处理机制分析(28)