Qt5開發安卓調試工具(adb shell input以及adb shell screencap應用)
文章目錄
一、前言
最新的物聯網項目之前說過是安卓機頂盒的軟探針項目,目前項目前期基本開發完了,這個時候就涉及到維護問題了,維護的時候由於是遠程維護,不可能有一點問題就到出差去開發,而且最近疫情限制到現場都不現實,然後我們就考慮遠程維護的問題,之前遠程通過TeamViewer連接電腦然後視頻去讓遠程的人操作電視機頂盒,但是這個很浪費人力資源,而且遠程的人需要一直待命,這個就很麻煩。我們同事間討論的時候就說他之前由於沒有多餘的遙控器發現了一個adb shell input的命令,可以通過adb shell命令行狀態下控制機頂盒,上下左右啥的基本遙控器能做的都能做到,然後再加上adb shell screencap的Android屏幕截圖功能,一個控制機頂盒,一個顯示當前位置,這樣配合着使用就能做到簡單的無人值守可視化操作機頂盒了。考慮到安卓、pyQt程序執行時需要安裝環境,最後綜合考慮使用Qt來實現這個調試軟件。
二、技術點
前期查閱資料準備了下,QProcess實現執行adb等命令然後顯示執行結果,簡單的QPushbutton來模擬常用的遙控器按鍵,當按下按鈕後調用adb shell input進行機頂盒控制,執行成功後再調用adb shell sreencap來抓取屏幕的截圖,最後利用Qlabel顯示截圖即可,思路簡單清晰。
- 1、QProcess執行命令
- 2、adb shell input發送安卓控制命令
- 3、adb shell sreencap截取屏幕
- 4、Qlabel顯示圖片
三、技術點實現及坑點記錄
1、QProcess執行命令
我們可以先用Qt助手瞭解一下QProcess類:
和串口操作類似,支持異步和同步方式,因爲我們不需要執行長時間的命令,所以最後打算這裏先使用同步阻塞式讀寫操作。
找到這個簡單的例子:
然後,我們在windows下可以使用cmd執行指令,這個是個簡單的例子:
QProcess pCmd;
//cmmand通過傳參傳進來
pCmd.start("cmd", QStringList()<<"/c"<<command);
if (!pCmd.waitForStarted())
return false;
if (!pCmd.waitForFinished())
return false;
QString strTemp=QString::fromLocal8Bit(p.readAllStandardOutput());
ui->textBrowser_DebugInfo->append(strTemp);
return true;
還有一些其它的用法,比如我們像調用寫好的python、shell、bat腳本或者調用其它程序等,則可以按照最上面的示例去嘗試:
QString program = "./path/to/Qt/examples/widgets/analogclock";
QStringList arguments;
arguments << "-style" << "fusion";
QProcess *myProcess = new QProcess(parent);
myProcess->start(program, arguments);
2、adb shell input發送安卓控制命令
輸入adb shell input瞭解一下用法:
example:example~$ adb shell input
Usage: input [<source>] <command> [<arg>...]
The sources are:
trackball(軌跡球)
joystick(操縱桿)
touchnavigation(觸摸導航)
mouse(鼠標)
keyboard(鍵盤)
gamepad(遊戲手柄)
touchpad(觸摸板)
dpad(apad手柄)
stylus(輸入筆)
touchscreen(觸摸屏)
The commands and default sources are:
text <string> (Default: touchscreen)
keyevent [--longpress] <key code number or name> ... (Default: keyboard)
tap <x> <y> (Default: touchscreen)
swipe <x1> <y1> <x2> <y2> [duration(ms)] (Default: touchscreen)
press (Default: trackball)
roll <dx> <dy> (Default: trackball)
我們這裏用的就是keyevent,前面的source就是默認的keyboard,所以基本上這裏的指令會是:
adb shell input keyevent xxx
這裏xxx的獲取我們一般可以先用adb logcat | grep keycode來過濾keycode,然後使用遙控器按一下我們需要模擬的上下左右、ok、菜單、設置等鍵來獲取對應的keycode值,比如我這裏獲取到的值如下:
#設置
adb shell input keyevent 176
#菜單
adb shell input keyevent 82
#上、下、左、右、ok
adb shell input keyevent 19
adb shell input keyevent 20
adb shell input keyevent 21
adb shell input keyevent 22
adb shell input keyevent 23
#首頁
adb shell input keyevent 3
#返回
adb shell input keyevent 4
3、adb shell sreencap截取屏幕
先了解一下adb shell screencap的用法:
zy@ZY:~$ adb shell screencap ?
usage: screencap [-hp] [-d display-id] [FILENAME]
example: screencap -p /sdcard/screencap.png
-h: this message
-p: save the file as a png.
-d: specify the display id to capture, default 1.
If FILENAME ends with .png it will be saved as a png.
If FILENAME ends with .jpg it will be saved as a jpg.
If FILENAME is not given, the results will be printed to stdout.
例子也給了:
screencap -p /sdcard/screencap.png
-h和?一樣都是顯示這個命令的usage,-p是將截取保存爲文件,文件的後綴是.png就是png圖片,後綴是.jpg則是jpg圖片,不給路徑就輸入到屏幕。
adb shell screencap -p /sdcard/1.jpg
或者
adb shell screencap -p /sdcard/1.png
或者
adb shell screencap(輸出到終端,基本就是亂碼)
注意:這裏我之前都是存了png圖片,但是在Qt中用label顯示的時候一直加載識別不了,找了很久都不行,最後改成存jpg才正確顯示出來。
4、Qlabel顯示圖片
這個其實很簡單,將圖片轉換成像素後用label顯示即可:
QPixmap pixmap("1.jpg");
screen_label.setWindowTitle("機頂盒屏幕截圖");
screen_label.setPixmap(pixmap);
screen_label.show();
screen_label就是顯示圖片的label,會自動根據圖片大小進行調整。
理論上QPixmap可以讀取png圖片,但是我在處理的時候一直不行,這個注意一下。
5、坑點
主要就是label顯示截圖的時候,開始我一直截圖是png格式,但是一直空白的,最後查了很久覺得很可能是由於png透明顯示了,還以爲哪裏沒有設置好,最後改成jpg正常顯示了,如果png沒有顯示出來可以看下換個jpg是不是可以正常顯示。
四、最後
展示一下效果吧,思路說完了,其實實現起來很簡單的,大家可以自己想想實現一下。
該項目目前已開源至碼雲和GitHub,以下是碼雲地址:https://gitee.com/yaoyecaizi/AndroidSTBDebugTools