Android串口編程
用到谷歌開源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 = [] }
}
- 1
- 2
- 3
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;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
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));
}
};
});
智能推薦
串口編程案例
前提準備 虛擬串口 串口調試助手 其他資源 模擬COM1串口發送信息到COM2接收 首先、下載虛擬串口進行安裝,安裝完后打開軟件(漢化過程忽略) 右鍵打開計算機–>管理–>設備管理器–>端口 打開VS,新建項目(Windows 應用程序) 下載串口調試助手,打開 用串口調試助手發送,效果如圖: 簡單串口編程結束!...
比特說串口編程
要說一種植物,從種子發芽開始.要說計算機,從源頭開始. 在1.X系列的文章中,我們從最開始的燈泡的例子開始,一步步深入,知道了CPU是怎么工作的,配合內存可以自動工作。 前面的內容基本上是CPU工作原理的完整輪廓了。 我們知道現在使用的各種形態的計算機除了CPU還有很多別的設備,這些所有的設備都不在CPU里面,都是外部設備,簡稱:外設。常見外設有:鍵盤,鼠...
七、Linux串口編程
Linux下的串口編程過程如下(我就不給大家再講串口是什么了,不懂得朋友自行補上串口相關知識): 目錄 一、打開串口 二、初始化串口 1、 串口的初始化結構介紹 2、串口的初始化常用函數介紹 函數 tcgetattr 波特率相關的函數 cfsetispeed 和 cfsetospeed、cfgetispeed 、cfgetospeed 函數 tcflush 函數 tcseta...
樹莓派串口編程
串口通信通常用在多機通信中 比如樹莓派和語言模塊的通信 數據在T和R之間通信,這時全雙工的 全雙工:兩個人互相罵 半雙工: 講話的時候另一個人閉嘴 通信要求:1、語言相通 ——》數據格式 2、語速正常 ——》波特率 比如用串口使用樹莓派時,選擇了115200。 數據位,停止位,奇偶校驗位就是數據格式 如果不寫驅動,就要用到wiringPi 參考如下 ...
猜你喜歡
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...
Linux C系統編程-線程互斥鎖(四)
互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...