2010-08-13 13 views
10

Ich versuche, einen Stapel zu schreiben (für Win) und ein Shell-Skript für Linux zu Schlüssel und Touch-Ereignisse auf einer Android-Benutzeroberfläche zu automatisieren. Im Moment in einer Windows-Batch-Datei fange ich eine adb shell für jedes Ereignis für zBshell/batch scripting, um Befehle an adb shell zu leiten

: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 

Der obige Code ist jedes Mal eine neue adb shell infact starten. Ich möchte das vermeiden. Ich möchte, dass mein Batch-Skript die Adb-Shell nur einmal startet und ich möchte das Kommando sendevent und andere Befehle an die Subshell, dh die Adb-Shell, weiterleiten.

Irgendeine Idee, wie ich dies in Win Batch und Lin Shell-Skript tun kann?

Antwort

10

Ich weiß nicht viel über Batch-Scripting oder Shell-Skripten, aber ich war in der Lage ein Java-Programm schnell zu schreiben, dies zu tun:

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(); 
    } 
} 

Sie können dann, wie Sie diese Klasse in einem Shell-Skript verwenden wie das Übergeben der Befehle, die als Befehlszeilenargumente in Ihrer Hauptmethode ausgeführt werden sollen.

z.B. Im Folgenden finden Sie das Shell-Skript:

#!/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

coole Antwort, nur kleiner Fehler, der Thread t sollte keine Methode haben Anwendungsbereich –

2

Eine weitere Möglichkeit, die folgenden zu gehen:

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" 
+0

Nur realisiert Sie verwenden eine Batch-Datei. Das obige funktioniert in bash, aber ich erinnere mich nicht, wie DOS Zeilenfortsetzung behandelt. Vielleicht funktioniert das wie es ist? Die Semikolons sind alles, was nötig ist, um mehrere Befehle an die adb-Shell zu senden (was ash IIRC ist) – Topher

8

Tophers Antwort ist fast richtig.

Entfernen Sie einfach die Zeilenumbrüche und es funktioniert.

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;" 

Das einzige, was Sie kümmern sich nehmen müssen, dass Sie nicht in mehr als 25 füttern (das ist die Menge, die ich verwendet, 30 doesn Arbeit mehr) sendevents, weil sonst adb den Fehler werfen, dass Es gibt zu viele Argumente oder so.

+0

Danke. Deine Antwort hat mir geholfen. –

+0

@Vladimir, was ist, wenn meine Shell-Befehle Zitate enthalten? Zum Beispiel, 'adb Shell Eingabetext" blah-blah "' – stansult

10

Setzen Sie alle Befehle, die Sie wollen auf einmal in einer externen Datei ausgeführt werden, eine pro Zeile, dann laufen:

adb shell < commands.txt 
6

ich etwas Ähnliches tue

(
    echo cd sdcard 
    echo ls 
) | adb shell 

So kann es funktionieren wie unten:

(
    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