我正在尝试编写一个批处理(for win)和一个用于linux的shell脚本,以自动化Android UI上的键和触摸事件。在Windows批处理文件中,我正在为例如
的每个事件启动一个adb shell :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 shell。我想避免这种情况。我希望我的批处理脚本只启动adb shell一次,我想将sendevent和其他命令路由到子shell,即adb shell。
任何想法如何在win batch和Lin shell脚本中做到这一点?
答案 0 :(得分:15)
将您想要一次运行的所有命令放在外部文件中,每行一个,然后运行:
adb shell < commands.txt
答案 1 :(得分:10)
我对批处理脚本或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脚本中使用此类,因为您希望将命令作为主方法中的命令行参数执行。
e.g。下面是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"
答案 2 :(得分:10)
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不再工作)sendevents,因为否则adb会抛出错误,有太多争论左右。
答案 3 :(得分:6)
我正在做类似的事情
(
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
答案 4 :(得分:2)
另一种方法是:
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"