我试图为
linux编写一个批处理(for win)和一个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和其他命令路由到subshell,即adb shell.
有什么想法我可以在win batch和lin shell脚本中做到这一点吗?
解决方法
我不太了解批处理脚本或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,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"