外壳/批次脚本直接命令到ADB Shell
-
28-09-2019 - |
题
我正在尝试编写一批(赢)和一个shell脚本,以使Linux自动化键并在Android UI上触摸事件。目前,在Windows批处理文件中,我正在为每个事件开始一个ADB外壳
:again
adb shell am start -a android.intent.action.MAIN -n com.q.me.fui.activity/.InitActivity
sleep 15
adb shell sendevent /dev/input/event0 3 0 281
adb shell sendevent /dev/input/event0 3 1 70
adb shell sendevent /dev/input/event0 1 330 1
adb shell sendevent /dev/input/event0 0 0 0
adb shell sendevent /dev/input/event0 1 330 0
adb shell sendevent /dev/input/event0 0 0 0
adb shell sendevent /dev/input/event0 1 330 1
adb shell sendevent /dev/input/event0 0 0 0
adb shell sendevent /dev/input/event0 1 330 0
adb shell sendevent /dev/input/event0 0 0 0
adb shell sendevent /dev/input/event0 0 0 0
adb shell sendevent /dev/input/event0 0 0 0
sleep 5
adb shell input keyevent 82
adb shell input keyevent 20
adb shell input keyevent 20
adb shell input keyevent 22
adb shell input keyevent 22
adb shell input keyevent 22
adb shell input keyevent 66
sleep 5
goto again
上面的代码实际上是每次启动新的ADB外壳。我想避免这种情况。我希望我的批处理脚本仅启动ADB shell一次,我想将sendevent和其他命令路由到子壳,即ADB Shell。
知道我如何在Win Batch和Lin Shell脚本中做到这一点?
解决方案
我对批次脚本或外壳脚本不太了解,但是我能够迅速编写Java程序来做到这一点:
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
public class AndroidShell {
private ProcessBuilder builder;
private Process adb;
private static final byte[] LS = "\n".getBytes();
private OutputStream processInput;
private InputStream processOutput;
private Thread t;
/**
* Starts the shell
*/
public void start() throws IOException {
builder = new ProcessBuilder("adb", "shell");
adb = builder.start();
// reads from the process output
processInput = adb.getOutputStream();
// sends to process's input
processOutput = adb.getInputStream();
// thread that reads process's output and prints it to system.out
Thread t = new Thread() {
public void run() {
try {
int c = 0;
byte[] buffer = new byte[2048];
while((c = processOutput.read(buffer)) != -1) {
System.out.write(buffer, 0, c);
}
}catch(Exception e) {}
}
};
t.start();
}
/**
* Stop the shell;
*/
public void stop() {
try {
if(processOutput != null && t != null) {
this.execCommand("exit");
processOutput.close();
}
}catch(Exception ignore) {}
}
/**
* Executes a command on the shell
* @param adbCommand the command line.
* e.g. "am start -a android.intent.action.MAIN -n com.q.me.fui.activity/.InitActivity"
*/
public void execCommand(String adbCommand) throws IOException {
processInput.write(adbCommand.getBytes());
processInput.write(LS);
processInput.flush();
}
public static void main(String[] args) throws Exception {
AndroidShell shell = new AndroidShell();
shell.start();
for(String arg : args) {
if(arg.startsWith("sleep")) {
String sleep = arg.split(" ")[1].trim();
long sleepTime = Integer.parseInt(sleep) * 1000;
Thread.sleep(sleepTime);
}else {
shell.execCommand(arg);
}
}
shell.stop();
}
}
然后,您可以在Shell脚本中使用此类,因为您喜欢将命令传递给主方法中的命令行参数。
例如,下面是Shell脚本:
#!/bin/bash
java AndroidShell "am start -a android.intent.action.MAIN -n com.q.me.fui.activity/.InitActivity" \
"sleep 15" \
"sendevent /dev/input/event0 3 0 281" \
"sendevent /dev/input/event0 3 1 70" \
"sendevent /dev/input/event0 1 330 1" \
"sendevent /dev/input/event0 0 0 0" \
"sleep 10" \
"sendevent /dev/input/event0 1 330 0" \
"exit"
其他提示
将您要一次运行的所有命令在外部文件中,每行1个,然后运行:
adb shell < commands.txt
Topher的答案几乎是正确的。
只需删除新线,它就会起作用。
adb shell "sendevent /dev/input/event9 3 53 215;sendevent /dev/input/event9 3 54 68;sendevent /dev/input/event9 3 48 40;sendevent /dev/input/event9 3 50 6;sendevent /dev/input/event9 3 57 0;sendevent /dev/input/event9 0 2 0;sendevent /dev/input/event9 0 0 0;sendevent /dev/input/event9 3 53 215;sendevent /dev/input/event9 3 54 68;sendevent /dev/input/event9 3 48 0;sendevent /dev/input/event9 3 50 6;sendevent /dev/input/event9 3 57 0;sendevent /dev/input/event9 0 2 0;sendevent /dev/input/event9 0 0 0;"
您唯一需要照顾的是,您不会以超过25次(这是我使用的金额,30次工作),因为否则ADB会抛出错误,以至于有太多参数左右。
我正在做类似的事情
(
echo cd sdcard
echo ls
) | adb shell
因此,它可以如下工作:
(
echo am start -a android.intent.action.MAIN -n com.q.me.fui.activity/.InitActivity
echo sleep 15
echo sendevent /dev/input/event0 3 0 281
echo sendevent /dev/input/event0 3 1 70
echo sendevent /dev/input/event0 1 330 1
echo sendevent /dev/input/event0 0 0 0
echo sendevent /dev/input/event0 1 330 0
echo sendevent /dev/input/event0 0 0 0
echo sendevent /dev/input/event0 1 330 1
echo sendevent /dev/input/event0 0 0 0
echo sendevent /dev/input/event0 1 330 0
echo sendevent /dev/input/event0 0 0 0
echo sendevent /dev/input/event0 0 0 0
echo sendevent /dev/input/event0 0 0 0
echo sleep 5
echo input keyevent 82
echo input keyevent 20
echo input keyevent 20
echo input keyevent 22
echo input keyevent 22
echo input keyevent 22
echo input keyevent 66
echo sleep 5
) | adb shell
另一种方法是以下方法:
adb shell "sendevent /dev/input/event0 3 0 281;
sendevent /dev/input/event0 3 1 70;
sendevent /dev/input/event0 1 330 1;
sendevent /dev/input/event0 0 0 0;
sendevent /dev/input/event0 1 330 0;
sendevent /dev/input/event0 0 0 0;
sendevent /dev/input/event0 1 330 1;
sendevent /dev/input/event0 0 0 0;
sendevent /dev/input/event0 1 330 0;
sendevent /dev/input/event0 0 0 0;
sendevent /dev/input/event0 0 0 0;
sendevent /dev/input/event0 0 0 0"
不隶属于 StackOverflow