1. 程式人生 > >Android 模擬器串列埠與PC虛擬串列埠通訊

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哈