2013-02-18 12 views
27

È possibile simulare il tocco dall'applicazione (o servizio) in background o eseguire sh script (che simula il tocco)?Come simulare il tocco dal servizio in background con sendevent o in altro modo?

È necessario per testare il sistema Android senza USB o altra connessione al PC, ecco perché non posso (o non so come) usare Monkey o altri strumenti di autotest.

informazioni Aggiunto: ho trovato il modo di eseguire comandi di shell con radice (dispositivi testati radicate):

Unable to execute sendevent shell command through the android code (creare simulazione touch). Writing file on system partition (esegui i comandi con i permessi di root)

Inoltre ricevo eventi per simulare il tocco.

Come risultato ho:

//sendevent commands to simulate touch (verify it work from cmd) 
String[] touchEvent = { "sendevent /dev/input/event0 0 0 0\n", 
         "sendevent /dev/input/event6 3 53 499\n", 
         "sendevent /dev/input/event6 3 54 680\n", 
         "sendevent /dev/input/event6 3 58 40\n", 
         "sendevent /dev/input/event6 3 48 3\n", 
         "sendevent /dev/input/event6 3 57 0\n", 
         "sendevent /dev/input/event6 0 2 0\n", 
         "sendevent /dev/input/event6 0 0 0\n", 
         "sendevent /dev/input/event6 0 2 0\n", 
         "sendevent /dev/input/event6 0 0 0\n", 
         "sendevent /dev/input/event0 3 0 2\n", 
         "sendevent /dev/input/event0 0 0 0\n"}; 

try{ 
    Thread.sleep(2000); 
    Process root = Runtime.getRuntime().exec("su"); 
    DataOutputStream os = new DataOutputStream(root.getOutputStream());    
    for(int i = 0; i < touchEvent.length; i++){ 
      Log.i(TAG, touchEvent[i]); 
      os.writeBytes(touchEvent[i]); 
      os.flush(); 
    } 
    root.waitFor(); 
} catch (IOException e) { 
    Log.e(TAG, "Runtime problems\n"); 
    e.printStackTrace(); 
} catch (SecurityException se){ 
    se.printStackTrace(); 
} catch (InterruptedException e) { 
    e.printStackTrace(); 
} 

Non ho alcuna eccezione, ma non è toccare Simula.

Qualcuno può aiutare a risolvere questo problema?

Se c'è un altro modo per farlo con Android ndk o daemon su C, per favore parlatene.

Grazie.

+0

se la vostra sulla stessa rete locale, è possibile utilizzare scimmia, adb funzionerà su reti wireless pure. – L7ColWinters

+0

Grazie per la risposta. Lo so, ma non dovrebbe esserci alcuna connessione (WiFi e BT dovrebbero essere spenti). – v1k

+0

Ciao, come puoi realizzare questo? Ho seguito tutti i vostri passi, ma non una buona notizia, si prega di consultare la mia domanda che avevo postato [qui] (http://stackoverflow.com/questions/42745005/android-self-signed-apk) –

risposta

28

Non riesco a eseguire il comando "sendevent", ma ho trovato un altro modo per me stesso, spero che possa essere d'aiuto per qualcuno.

Per simulare il tocco ho utilizzato sendPointerSync() da android.app.Instrumentation, che funziona solo con l'autorizzazione "android.permission.INJECT_EVENTS". Per utilizzarlo dovresti compilare la tua app come app di sistema. Per farlo è necessario seguire prossimi passi:

  1. ottenere un file da source Android:

    radice-di-android-fonte-albero/out/host // quadro/signapk.jar

    radice-di-android-fonte-albero/costruire/target/prodotto/sicurezza/platform.x509.pem

    radice-di-android-fonte-albero/costruire/target/prodotto/sicurezza/platform.pk8

  2. firmare la vostra applicazione utilizzando i file di ottenere:

    comando "java-jar signapk.jar platform.x509.pem platform.pk8 YourApp-unsigned.apk "YourApp-signed.apk.

  3. adb install YourApp-signed.apk
    • Eseguire la vostra applicazione
    • Usa "adb shell ps" per confermare che la vostra applicazione è in esecuzione come sistema.

codice con touch simulando (nuovo thread è necessario per la simulazione):

Thread thread = new Thread(){ 
     @Override 
     public void run(){ 
       Instrumentation m_Instrumentation = new Instrumentation(); 

       m_Instrumentation.sendPointerSync(MotionEvent.obtain(
         SystemClock.uptimeMillis(), 
         SystemClock.uptimeMillis(), 
         MotionEvent.ACTION_DOWN,posx, posy, 0)); 
       m_Instrumentation.sendPointerSync(MotionEvent.obtain(
         SystemClock.uptimeMillis(), 
         SystemClock.uptimeMillis(), 
         MotionEvent.ACTION_UP,width*4/5,height, 0)); 
     } 
    }; 

Manifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.example.yourapp" 
    **android:sharedUserId="android.uid.system"** 
    android:versionCode="1" 
    android:versionName="1.0" > 

Uso delle risorse:

+1

Ciao, fa questo lavoro da un background servizio? – Dania

+0

Ciao, sì, dovrebbe. Ma non dimenticare di creare thread. – v1k

+0

Grande, grazie. Puoi dirmi per favore qual è stata la versione di Android su cui hai testato il codice? La strumentazione funziona bene con le versioni precedenti a Lollipop. Penso che Lollipop abbia bisogno di qualche lavoro in più per far funzionare la strumentazione, hai affrontato questo problema? O conosci qualche possibile soluzione? – Dania

24

Stavo per implementare la soluzione quando ho trovato uno più facile - posting nella speranza che sarà utile a qualcuno. Poiché hai già un dispositivo rooted, non devi firmare come app di sistema.

Per simulare un tocco alla posizione (100.200), tutto quello che dovete è chiamare ingresso dall'interno del servizio utilizzando Runtime.exec come segue:

Process process = Runtime.getRuntime().exec("su"); 
DataOutputStream os = new DataOutputStream(process.getOutputStream()); 
String cmd = "/system/bin/input tap 100 200\n"; 
os.writeBytes(cmd); 
os.writeBytes("exit\n"); 
os.flush(); 
os.close(); 
process.waitFor(); 
+1

Questa è una soluzione molto più pulita. Sfortunatamente non ha eventi come touch_down, touch_up o move_to, che sono molto necessari a me. :( –

+0

Grazie, ha funzionato sulla mia ROM di default della galassia s4 5.0.1 ma funziona raramente su alcuni dispositivi come galassia s6 6.0.1 rooted.E 'così stanco! Perché? –

3

È possibile utilizzare il "colpo" ingresso. Guardando il Input.java source code puoi vedere i parametri necessari per fare uno swipe.

Ecco uno gist I made for simulating a swipe per la riproduzione dello smove game con clic anziché passaggi solo per testarlo. Hai bisogno di un accesso da super utente per usare questa implementazione.

+6

Potresti fare una modifica per includere lo snippet di codice examplish dimostrando questo soluzione? Questo è sul punto di essere una risposta "link-only". – bardzusny

+0

il codice sorgente è in realtà abbastanza ovvio e autoesplicativo. per swipe: 'com.android.commands.input.Input.main (new String [] { "touchscreen", "scorri", "", "", "", "" [, ""]}) '(" touchscreen "è opzionale in un certo senso, ma meglio presentato. chiedi è che il codice funziona davvero? e ho bisogno di una dichiarazione per il permesso in AndroidManifest.xml o ho bisogno di un accesso root? – Valen

+0

^fai riferimento a quello sopra: usa '" blah blah ".split (" ")' per una migliore visualizzazione esprimere ione – Valen

Problemi correlati