Qt5 develops Android debugging tools (adb shell input and adb shell screencap applications)

This article has participated in the "Newcomer Creation Ceremony" event to start the road of gold creation together.

I. Introduction

The latest Internet of Things project was said to be a soft probe project for Android set-top boxes. At present, the project has basically been developed in the early stage. At this time, maintenance problems are involved. Since the maintenance is remote maintenance, it is impossible to go on a business trip if there is a problem. Development, and it is unrealistic to limit the epidemic to the scene recently, and then we considered the problem of remote maintenance. Before, the remote connected to the computer through TeamViewer and then video to let the remote person operate the TV set-top box, but this is a waste of human resources, and the remote person needs It's very troublesome to be on standby all the time. When discussing among our colleagues, we said that he had found an adb shell input command because he had no extra remote control. He could control the set-top box through the adb shell command line state, and the basic remote control of up, down, left, and right can do everything. , and then add the Android screen capture function of adb shell screencap, one to control the set-top box, and the other to display the current position, so that it can be used together to achieve a simple unattended visual operation of the set-top box. Considering that the Android and pyQt programs need to be installed when the program is executed, we finally consider using Qt to implement this debugging software.

2. Technical points

After reading the data in the early stage, QProcess implements commands such as adb and then displays the execution results. A simple QPushbutton simulates the commonly used remote control buttons. When the button is pressed, adb shell input is called to control the set-top box. After the execution is successful, adb shell sreencap is called. To grab a screenshot of the screen, and finally use Qlabel to display the screenshot, the idea is simple and clear.

  • 1. QProcess executes the command
  • 2. adb shell input sends Android control commands
  • 3, adb shell sreencap screenshot screen
  • 4. Qlabel display picture

3. Technical point realization and pit record

1. QProcess executes the command

We can first use the Qt assistant to learn about the QProcess class: 在这里插入图片描述similar to serial port operations, it supports asynchronous and synchronous methods. Because we do not need to execute long-term commands, we finally plan to use synchronous blocking read and write operations here. Find this simple example: 在这里插入图片描述Then, we can use cmd to execute commands under windows, this is a simple example:

	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;

There are some other usages, such as calling the written python, shell, bat script or calling other programs, etc., you can try it according to the above example:

	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 sends Android control commands

Enter adb shell input to understand the usage:

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)

What we use here is keyevent, the previous source is the default keyboard, so basically the instructions here will be:

adb shell input keyevent xxx

To obtain xxx here, we can generally use adb logcat | grep keycode to filter the keycode, and then use the remote control to press the keys we need to simulate, such as up, down, left, ok, menu, settings, etc. to obtain the corresponding keycode value, for example, I obtained here The values ​​are as follows:

#设置
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 screenshot screen

First understand the usage of 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.

Example also gives:

screencap -p /sdcard/screencap.png

-h and ? The same is to display the usage of this command, -p is to save the interception as a file, the suffix of the file is .png is a png image, and the suffix is ​​.jpg is a jpg image, input to the screen without giving a path.

adb shell screencap -p /sdcard/1.jpg
或者
adb shell screencap -p /sdcard/1.png
或者
adb shell screencap(输出到终端,基本就是乱码)

Note: I have saved png images here before, but when I displayed them with labels in Qt, they could not be loaded and recognized. I couldn't find them for a long time. Finally, I changed them to jpg before they were displayed correctly.

4. Qlabel display picture

This is actually very simple, convert the image into pixels and display it with a label:

	QPixmap pixmap("1.jpg");
    screen_label.setWindowTitle("机顶盒屏幕截图");
    screen_label.setPixmap(pixmap);
    screen_label.show();

screen_label is the label that displays the picture, which will be automatically adjusted according to the size of the picture.

In theory, QPixmap can read png images, but I have been unable to process them, so pay attention to this.

5. Pit

主要就是label显示截图的时候,开始我一直截图是png格式,但是一直空白的,最后查了很久觉得很可能是由于png透明显示了,还以为哪里没有设置好,最后改成jpg正常显示了,如果png没有显示出来可以看下换个jpg是不是可以正常显示。

四、最后

展示一下效果吧,思路说完了,其实实现起来很简单的,大家可以自己想想实现一下。 在这里插入图片描述 该项目目前已开源至码云和GitHub,以下是码云地址:gitee.com/yaoyecaizi/…

Guess you like

Origin juejin.im/post/7118167811435790373