Я пытаюсь написать пакет (для победы) и сценарий оболочки для 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 только один раз, и я хотел бы направить sendevent и другие команды в подоболочку, то есть оболочку adb.
Есть идеи, как я могу сделать это в пакете win и сценарии оболочки Lin?
Я мало что знаю о пакетных сценариях или сценариях оболочки, но мне удалось быстро написать 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();
}
}
Затем вы можете использовать этот класс в сценарии оболочки как вам нравится передавать команды для выполнения в качестве аргументов командной строки в вашем основном методе.
например. Ниже приведен сценарий оболочки:
#!/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"