Android串口通信可以實現設備與設備之間通過設備線連接進行數據(消息)傳遞
(一)導入so庫

(二)在moudle的build中添加jniLibs
buildTypes {
sourceSets {
main { jni.srcDirs = [] }
}
}
12345(三)添加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;
}
}
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131package 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;
}
}
123456789101112131415161718192021222324252627282930313233343536373839package 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;
}
}
}
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374Demo——github地址
原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/224773.html
微信掃一掃
支付寶掃一掃