Android串列埠通訊(Android Studio)
阿新 • • 發佈:2019-02-18
用到谷歌開源serialPort api
下載連結:serialPort-api
以下專案用的so庫是谷歌原庫,沒有做修改
新建專案:
1、先把下載的api中這些檔案拷進專案的相應位置
SerialPort類是咱們Android可以呼叫的類,
jni目錄下放著c原始碼和h標頭檔案,
jniLibs下面放的就是so庫。
注意:因為用的谷歌原生so庫,所以SerialPort類的包名一定要是android_serialport_api,如果想修改這個包名,就需要重新生成對應的so庫
這是SerialPort類,裡面的open和close方法在報錯,這個不用管。
2、在build.gradle中新增如下程式碼:
sourceSets {
main { jni.srcDirs = [] }
}
3、這樣就可以串列埠通訊了
這是串列埠操作類:
package utils;
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;
/**
* Created by WangChaowei on 2017/12/7.
*/
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(){
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;
}
}
4、activity中只貼串列埠資料監聽事件
//串列埠資料監聽事件
serialPortUtils.setOnDataReceiveListener(new SerialPortUtils.OnDataReceiveListener() {
@Override
public void onDataReceive(byte[] buffer, int size) {
Log.d(TAG, "進入資料監聽事件中。。。" + new String(buffer));
//
//線上程中直接操作UI會報異常:ViewRootImpl$CalledFromWrongThreadException
//解決方法:handler
//
mBuffer = buffer;
handler.post(runnable);
}
//開執行緒更新UI
Runnable runnable = new Runnable() {
@Override
public void run() {
textView_status.setText("size:"+ String.valueOf(mBuffer.length)+"資料監聽:"+ new String(mBuffer));
}
};
});