2010-08-13 11 views
10

Sto provando a scrivere un batch (per win) e uno script di shell per linux per automatizzare gli eventi key e touch su un'interfaccia utente Android. Al momento in un file batch di Windows Sto iniziando un adb shell per ogni evento per esempioscript di shell/batch per dirigere i comandi ad 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 

Il codice di cui sopra è infatti iniziare una nuova adb shell ogni volta. Voglio evitare questo. Voglio che il mio script batch avvii la shell adb solo una volta e vorrei indirizzare sendevent e altri comandi alla subshell, cioè la shell adb.

Qualche idea su come posso farlo nello script di batch batch e lin shell?

risposta

10

io non so molto di script batch o scripting di shell, ma sono stato in grado di scrivere velocemente un programma Java per fare questo:

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

È quindi possibile utilizzare questa classe in uno script di shell, come si come passare i comandi da eseguire come argomenti della riga di comando nel metodo principale.

ad es. Di seguito è riportato lo script di 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" 
+1

risposta semplice, solo piccolo errore, il thread t non deve avere il metodo scope –

2

Un altro modo per andare è la seguente: risposta

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

Appena realizzato stai usando un file batch. Quanto sopra funziona in bash ma non ricordo come DOS gestisca la continuazione della linea. Forse funzionerà così com'è? I punti e virgola sono tutto ciò che è necessario per inviare comandi multipli ad adb shell (che è ash IIRC) – Topher

8

di Topher è quasi corretto.

Basta rimuovere i newline e funzionerà.

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

L'unica cosa che dovete fare attenzione è che non si nutrono in più di 25 (che è la somma che ho usato, 30 lavoro doesn più) sendevents, perché altrimenti adb getterà l'errore, che ci sono troppi argomenti o giù di lì.

+0

Grazie. La tua risposta mi ha aiutato. –

+0

@Vladimir, e se i miei comandi di shell includessero virgolette? Ad esempio, 'testo di immissione della shell adb" blah-blah "' – stansult

10

mettere tutti i comandi che si desidera eseguire in una sola volta in un file esterno, uno per riga, quindi eseguire:

adb shell < commands.txt 
6

sto facendo qualcosa di simile

(
    echo cd sdcard 
    echo ls 
) | adb shell 

quindi potrebbe funzionare come sotto:

(
    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 
Problemi correlati