Android 串口通信
程序员文章站
2022-06-26 17:43:45
Android串口通信可以实现设备与设备之间通过设备线连接进行数据(消息)传递(一)导入so库(二)在moudle的build中添加jniLibsbuildTypes { sourceSets { main { jni.srcDirs = [] } } }(三)添加Googled的SerialPort添加的是Google的所以必须创建android_serialport_api包如需要更改SerialPort、SerialPor...
Android串口通信可以实现设备与设备之间通过设备线连接进行数据(消息)传递
(一)导入so库
(二)在moudle的build中添加jniLibs
buildTypes {
sourceSets {
main { jni.srcDirs = [] }
}
}
(三)添加Google的SerialPort
添加的是Google的所以必须创建android_serialport_api包
如需要更改SerialPort、SerialPortFinder位置需要重新生成so库
(四)创建串口通信工具类SerialPortUtils
package com.demo.serialport;
import android.util.Log;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android_serialport_api.SerialPort;
/**
* @author renquan
*/
public class SerialPortUtils {
private final String TAG = "SerialPortUtils";
// private String path = "/dev/ttyS1";
// private int baudrate = 9600;
public boolean serialPortStatus = false; //是否打开串口标志
public String data_;
public boolean threadStatus; //线程状态,为了安全终止线程
public SerialPort serialPort = null;
public InputStream inputStream = null;
public OutputStream outputStream = null;
public ChangeTool changeTool = new ChangeTool();
/**
* 打开串口
* @return serialPort串口对象
*/
public SerialPort openSerialPort(String path,int baudrate){
try {
serialPort = new SerialPort(new File(path),baudrate,0);
this.serialPortStatus = true;
threadStatus = false; //线程状态
//获取打开的串口中的输入输出流,以便于串口数据的收发
inputStream = serialPort.getInputStream();
outputStream = serialPort.getOutputStream();
new ReadThread().start(); //开始线程监控是否有数据要接收
} catch (IOException e) {
Log.e(TAG, "openSerialPort: 打开串口异常:" + e.toString());
return serialPort;
}
Log.d(TAG, "openSerialPort: 打开串口");
return serialPort;
}
/**
* 关闭串口
*/
public void closeSerialPort(){
try {
inputStream.close();
outputStream.close();
this.serialPortStatus = false;
this.threadStatus = true; //线程状态
serialPort.close();
} catch (IOException e) {
Log.e(TAG, "closeSerialPort: 关闭串口异常:"+e.toString());
return;
}
Log.d(TAG, "closeSerialPort: 关闭串口成功");
}
/**
* 发送串口指令(字符串)
* @param data String数据指令
*/
public void sendSerialPort(String data){
Log.d(TAG, "sendSerialPort: 发送数据");
try {
byte[] sendData = data.getBytes(); //string转byte[]
this.data_ = new String(sendData); //byte[]转string
if (sendData.length > 0) {
outputStream.write(sendData);
outputStream.write('\n');
//outputStream.write('\r'+'\n');
outputStream.flush();
Log.d(TAG, "sendSerialPort: 串口数据发送成功");
}
} catch (IOException e) {
Log.e(TAG, "sendSerialPort: 串口数据发送失败:"+e.toString());
}
}
/**
* 单开一线程,来读数据
*/
private class ReadThread extends Thread{
@Override
public void run() {
super.run();
//判断进程是否在运行,更安全的结束进程
while (!threadStatus){
Log.d(TAG, "进入线程run");
//64 1024
byte[] buffer = new byte[64];
int size; //读取数据的大小
try {
size = inputStream.read(buffer);
if (size > 0){
Log.d(TAG, "run: 接收到了数据:" + changeTool.ByteArrToHex(buffer));
Log.d(TAG, "run: 接收到了数据大小:" + String.valueOf(size));
onDataReceiveListener.onDataReceive(buffer,size);
}
} catch (IOException e) {
Log.e(TAG, "run: 数据读取异常:" +e.toString());
}
}
}
}
//数据回调
public OnDataReceiveListener onDataReceiveListener = null;
public static interface OnDataReceiveListener {
public void onDataReceive(byte[] buffer, int size);
}
public void setOnDataReceiveListener(OnDataReceiveListener dataReceiveListener) {
onDataReceiveListener = dataReceiveListener;
}
}
package com.demo.serialport;
/**
* @author renquan
*/
public class ChangeTool {
/**
* byte数组转16进制字符串
*
* @param bytes byte数组
* @return 16进制字符串
*/
public String ByteArrToHex(byte[] bytes) {
String strHex;
StringBuilder sb = new StringBuilder();
for (byte aByte : bytes) {
strHex = Integer.toHexString(aByte & 0xFF);
sb.append(" ").append((strHex.length() == 1) ? "0" : "").append(strHex); // 每个字节由两个字符表示,位数不够,高位补0
}
return sb.toString().trim();
}
/**
* byte字节转int
*
* @param b byte字节
* @return int
*/
public static int byteToInt(byte b) {
int x = b & 0xff;
if (x == 127) {
return 0;
}
return x;
}
}
package com.demo.serialport;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import androidx.appcompat.app.AppCompatActivity;
/**
* @author renquan
*/
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private EditText mMessage;
private Button mOpen;
private Button mSend;
private Button mClose;
private SerialPortUtils serialPortUtils;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
//串口数据监听事件
serialPortUtils.setOnDataReceiveListener(new SerialPortUtils.OnDataReceiveListener() {
@Override
public void onDataReceive(byte[] buffer, int size) {
Log.d("TAG", "进入数据监听事件中。。。" + new String(buffer));
}
});
}
private void init() {
initView();
serialPortUtils = new SerialPortUtils();
}
private void initView() {
mMessage = (EditText) findViewById(R.id.message);
mOpen = (Button) findViewById(R.id.open);
mOpen.setOnClickListener(this);
mSend = (Button) findViewById(R.id.send);
mSend.setOnClickListener(this);
mClose = (Button) findViewById(R.id.close);
mClose.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.open:
// TODO 20/12/28
serialPortUtils.openSerialPort("/dev/ttyS9",9600);
break;
case R.id.send:
// TODO 20/12/28
serialPortUtils.sendSerialPort(mSend.getText().toString());
break;
case R.id.close:
serialPortUtils.closeSerialPort();
// TODO 20/12/28
break;
default:
break;
}
}
}
本文地址:https://blog.csdn.net/weixin_45680654/article/details/111871351