第一次写博客,不知道说些什么,给大家拜个早年吧。
谷歌开源串口类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,实际上串口并未打开。
来源:oschina
链接:https://my.oschina.net/u/4316720/blog/4482014