Android 模擬器串列埠與PC虛擬串列埠通訊
1、開發環境
(1) Android Studio 3.0.1 (2) JDK 1.8 (3)
1、建立SerialPortNDKText 工程
2、在工程的main目錄下,建立jniLibs資料夾,如:E:\androidcode\SerialportNDKTest\app\src\main
jniLibs //注意資料夾名字,不要打錯,不然編譯是會報錯,而且非常難找
3、匯入相關平臺Serial_Port.so 庫,如我上一篇文章的生成的.so庫在工程目錄下
E:\androidcode\SerialPortNDK\app\build\intermediates\ndk\debug\lib
將上圖lib目錄的各個的.so庫libserial_port.so 複製到工程“SerialPortNDKText”的jniLibs目錄下。
4、新增SerialPort.java和SerialPortFinder.java檔案
注意:這兩個檔案存放的目錄必須和生成libSerialPort.so工程的相同,否則編譯時,會總是報錯,提示找不到xxx.so檔案
(2018.8.2 補充:上面這個問題估計是新手最容易犯的,因為在JNI工程中,SerialPort.java和SerialPortFinder.java所在的包生成
生成JNI.h 檔案已經包含兩個java所在的包名資訊,故在App 工程中,需要一致
我第一次操作的時候,就吃了這個大虧,這個問題足足搞了3個晚上.....所以一定要注意。。。
4.1 新建serialprot 包
4.2 匯入SerialPort.java和SerialPortFinder.java檔案
4.3 在MainActivti.xml 中新建兩個按鈕,一個用於開啟當前系統的串列埠,第二個用於測試傳送和接收資料
5、開啟模擬器命令
如果是筆記本,則一般是沒有串列埠的,因此如果想除錯串列埠,可以使用虛擬串列埠工具,如:
我使用的Configure Virtual Serial Port Driver.exe 這款軟體就非常好用,如圖:
5.1 我將COM1 和 COM2 虛擬出來,則表示C0M1 -> COM2 是相通的。
5.2 開啟串列埠除錯工具,如圖:
5.3 將模擬器繫結到Windows 的虛擬串列埠COM1 對映到Android 模擬器中,(提示,我除錯使用的Android 模擬器版本是4.4 對應API 版本
API19,而Android 5.0 以上的系統由於安全許可權不一樣,當執行SerialPort類的構造方法中下面程式碼,則會提示沒有許可權)
/* Check access permission */
if (!device.canRead() || !device.canWrite()) {
try {
/* Missing read/write permission, trying to chmod the file */
Process su;
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();
}
}
對於上面的問題,目前本人還是個菜鳥新人,還沒有找到解決辦法,如果有大神知道,可以給小弟提點意一下。
接著,win + r 開啟window 控制檯,輸入對映命令
對映的命令是:emulator @模擬器名字 -qemu -serial COMX(電腦串列埠號)
如我的,emulator @api -qemu -serial COM1
5.4 執行APP
5.4.1 模擬器傳送資料 -》串列埠助手接收資料:
5.4.2 模擬器接收資料 -》串列埠助手傳送資料
好了,終於完成了,使用串列埠助手和Android模擬器互相收發資料。
但是,目前還是存在三個沒有弄清楚的問題,有待解決。
第一個:就是使用模擬器,串列埠最大接收的位元組數是8位元組,超過這個數值模擬器就是類似死掉,毫無反應。
第二個:就是串列埠號與Linux 系統中的ttySxxxx 對應問題,如果對映的Windows串列埠號與app 開啟串列埠對不上,則會出現
下面的錯誤:tcgetattr() failed
D/serial_port: Opening serial port /dev/ttyS2 with flags 0x2
D/serial_port: open() fd = 46
D/serial_port: Configuring serial port
E/serial_port: tcgetattr() failed
E/SerialPort: nativeopen returns null
W/System.err: java.io.IOException
W/System.err: at chenxi.com.serialportjni.SerialPort.<init>(SerialPort.java:64)
W/System.err: at chenxi.com.serialportndktest.MainActivity$2.onClick(MainActivity.java:105)
W/System.err: at android.view.View.performClick(View.java:4438)
W/System.err: at android.view.View$PerformClick.run(View.java:18422)
W/System.err: at android.os.Handler.handleCallback(Handler.java:733)
W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
有些電腦使用的是網上很多使用的是 ttyS2, 而在我的模擬器上就會出現上面的問題,進過多次嘗試,使ttyS1 才能正常收發資料,這個問題需要再查查資料。
(2018.8.2 補充: 之前沒有把Linux 與 Android 聯絡起來,所以才沒有把這個疑問給想通,最近,在公司做專案需要做三個平臺的開發包Windows、Linux 和 Android,於是檢視Linux 串列埠一些資料,發現一般的:
1、檢視串列埠是否可用:可以對串列埠傳送資料比如對com1口,echo /dev/ttyS0
2、在Linux檢視串列埠名稱使用
ls -l /dev/ttyS*
一般情況下串列埠的名稱全部在dev下面,如果你沒有外插串列埠卡的話預設是dev下的ttyS*,一般ttyS0對應com1,ttyS1對應com2,當然也不一定是必然的;
而且在上面的 5.3提到我是”將模擬器繫結到Windows 的虛擬串列埠COM1 對映到Android 模擬器中“”所以,才有在開啟串列埠是需要使用的是ttyS1)
第三個:就是使用root的許可權修改串列埠許可權,有兩種情況,
(1)
su = Runtime.getRuntime().exec("/system/xbin/su");
(2)
su = Runtime.getRuntime().exec("/system/bin/su");
上面三個問題,還需要,多查查資料才行。
OK, 終於完成了。開心!!!!!!!!!!O(∩_∩)O哈