用于将命令定向到adb shell的shell / batch脚本

时间:2010-08-13 06:11:36

标签: android batch-file shell adb

我正在尝试编写一个批处理(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脚本中做到这一点?

5 个答案:

答案 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"