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;
}
}
}
Demo——github地址
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/241878.html
標籤:其他
上一篇:【CMake】CMake 引入 ( Android NDK 構建腳本 | CMake 命令手冊 )
下一篇:列印機后臺服務批處理
