android 串口一直打开_android 如何打开串口以及与串口通讯
串口通訊,對于沒接觸過這方面的朋友們,確實會感到頭疼,不知道從何下手。
其實,串口通訊和服務器之間的通訊是一樣的,都是傳一些參數過去,然后返回一些數據回來。不過串口通訊管這些參數叫做指令,而這些指令是由硬件的通訊協議而定的,通訊協議不同,指令自然也不同。在我開發的這個項目里,兼容了四種硬件通訊協議,這四種協議各不相同,所以,那些指令就不在代碼里面寫出來了。
串口通訊,第一步要做的當然是打開串口,打開串口的方法如下:
QQ截圖20161211220537.png
首先在app下建立一個libs文件夾,把.so文件復制到libs下
QQ截圖20161211220537.png
用android studio的朋友們要記得在build.gradle 文件中添加這段 jniLibs.srcDirs = ['libs'] ,我有一次看見別人的代碼里面可以不加這段,照樣能運行,有知道的可以和大家分享一下。不過這些都不重要,只要能開串口就行。然后,在java的根目錄下建一個包,注意是根目錄,包名為:android_serialport_api,這個包名是固定的,不能少也不能多。然后把類SerialPort復制到包下面。
// JNI
private native static FileDescriptor open(String path, int baudrate, int flags);
public native void close();
static { System.loadLibrary("serial_port"); }
上面的第一個函數open是調用jni打開串口的方法,調用該方法的時候會返回一個FileDescriptor對象,通過該對象可以獲取輸入輸出流。第二個close函數是關閉串口的方法,可以通過此方法關閉串口。這兩個函數最好是能成對出現,在程序打開的時候把串口打開,程序退出了就把串口關閉,這樣可以避免一些問題出現。第三個是加載.so文件里面的代碼的,加載了之后串口才能用。
···
public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException {
System.out.println("device======"+device.getAbsolutePath());
/* Check access permission /
if (!device.canRead() || !device.canWrite()) {
try {
/ Missing read/write permission, trying to chmod the file */
Process su = Runtime.getRuntime().exec("/system/bin/su");
String cmd = "chmod 666 " + device.getAbsolutePath() + "\n"
+ "exit\n";
su.getOutputStream().write(cmd.getBytes());
if ((su.waitFor() != 0) || !device.canRead()
|| !device.canWrite()) {
throw new SecurityException();
}
} catch (Exception e) {
e.printStackTrace();
throw new SecurityException();
}
}
mFd = open(device.getAbsolutePath(), baudrate, flags);
if (mFd == null) {
Log.e(TAG, "native open returns null");
throw new IOException();
}
mFileInputStream = new FileInputStream(mFd);
mFileOutputStream = new FileOutputStream(mFd);
}
···
上面的這段代碼中,su.getOutputStream().write(cmd.getBytes());這行是獲取root權限的,打開串口是需要root權限的,如果不能獲取root權限,串口也是打不開的,其他的就是一些判斷了,在這就不做詳細講解了。
上面這些是開串口之前的準備,準備完畢后,我們來打開串口,打開串口就是調用open函數,調用open函數需要傳三個參數,第一個參數path是串口名,比如:”/dev/ttyS0“,這些是根據實際接口來定的,第二個參數baudrate是波特率,一般都是9600,15200,這個需要根據硬件來定,第三個我就不清楚了,我都是傳0,有知道的可以和大家分享一下。
···
/**
* 初始化串口
* @param lockerPortInterface
/
private void setSerialPort(LockerPortInterface lockerPortInterface){
this.sportInterface = lockerPortInterface;
try {
/ Check parameters /
if ((path.length() == 0) || (baudrate == -1)) {
throw new InvalidParameterException();
}
/ Open the serial port */
boxPort = new SerialPort(new File(path), baudrate, 0);
mOutputStreamBox = boxPort.getOutputStream();
mInputStreamBox = boxPort.getInputStream();
/* Create a serial rec buf thread */
mReadThreadBox = new ReadThreadBox();
// SerialPortState = true;
mReadThreadBox.start();
if (firstRegisterBox) {
if(mContext == null){
Log.e(TAG, "mContext nulll");
}
m_SerialRecBox = new SerialBroadcastReceiverBox(mContext);
m_SerialRecBox.registerAction();
firstRegisterBox = false;
Log.i(TAG, "----locker port--- 注冊完畢");
}
lockerPortInterface.onLockerOutputStream(mOutputStreamBox);
} catch (SecurityException e) {
e.printStackTrace();
DisplayError(mContext,R.string.error_security);
} catch (IOException e) {
e.printStackTrace();
DisplayError(mContext,R.string.error_unknown);
} catch (InvalidParameterException e) {
e.printStackTrace();
DisplayError(mContext,R.string.error_configuration);
}
}
···
boxPort = new SerialPort(new File(path), baudrate, 0);這行代碼是調用SerialPort的構造方法,通過他的構造方法去調用open函數,然后通過SerialPort對象來獲取輸入輸出流。在這里解釋一下,輸入流是接收串口返回的數據,輸出流是向串口發指令。 調用SerialPort的構造方法可能會發生三種異常,第一種異常(SecurityException)是串口無讀寫權限,拋出這種異常的話就說明你可能沒有root權限,第二種異常(IOException )串口不能打開,可能就是你沒有這個串口,第三種異常(InvalidParameterException)是傳的參數有誤,可能是你的波特率不對。我理解的就是這樣的,不知道對不對。
openserialport.gif
這是我用模擬器測試的,只要有請求root權限的頁面,并且拋的是IO異常,打開串口應該就沒問題了。
最后就是向串口發指令,向串口發指令是用輸出流向串口寫入,至于具體的指令是什么,需要根據協議來定。發完指令之后串口會回數據結果給你,你需要接收這些數據來做業務,硬件不同,回數據結果的方式也不同,有些硬件是發完指令后把結果直接回給你,有些硬件是先給你一小部分,然后等1s再回另外一部分數據。
在我寫的demo里面用的方法是針對硬件一次性把數據結果全部返回的方式,onLockerDataReceived直接用這個方法接收數據,這樣就比較簡單了。串口通訊說到這里就結束了。
最后貼上自己寫的一個小demo地址:https://github.com/fm183/SerialportDemo.git,以供大家參考。
總結
以上是生活随笔為你收集整理的android 串口一直打开_android 如何打开串口以及与串口通讯的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微软Hololens学院教程- Holo
- 下一篇: js如何实现扫描身份证识别_如何识别身份