2014-04-18 16 views
6

Sto automatizzando il test di un flusso nella mia app in cui installo un amministratore del dispositivo. Per attivare un amministratore del dispositivo sulla maggior parte dei dispositivi (supponiamo che non disponga di alcune API aziendali che mi consentono di fare ciò che offre Samsung), il sistema visualizza un popup all'utente che deve quindi fare clic sul pulsante "Attiva".Come iniettare un evento click con Android UiAutomation.injectInputEvent

Sto usando Robotium e Android JUnit per guidare i miei test. In un normale caso di test si può interagire solo con l'app e il processo sotto test e non tutte le attività di sistema che emergono.

I UiAutomation reclami per consentono di interagire con altre applicazioni sfruttando la Accessibility Framework, e quindi permettendo di inject arbitrary input events.

Quindi - ecco quello che sto cercando di fare:

public class AbcTests extends ActivityInstrumentationTestCase2<AbcActivity> { 

    private Solo mSolo 

    @Override 
    public void setUp() { 
     mSolo = new Solo(getInstrumentation(), getActivity()); 

    } 

    ... 

    public void testAbc(){ 

     final UiAutomation automation = getInstrumentation().getUiAutomation();   

     MotionEvent motionDown = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), KeyEvent.ACTION_DOWN, 
       100, 100, 0); 

     // This line was added in to give a complete solution 
     motionDown.setSource(InputDevice.SOURCE_TOUCHSCREEN); 

     automation.injectInputEvent(motionDown, true) 
     MotionEvent motionUp = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), KeyEvent.ACTION_UP, 
       100, 100, 0); 

     // This line was added in to give a complete solution 
     motionUp.setSource(InputDevice.SOURCE_TOUCHSCREEN); 

     automation.injectInputEvent(motionUp, true) 
     motionUp.recycle(); 
     motionDown.recycle(); 
    } 

} 

Quando questo test viene eseguito il popup di sistema per "Attiva" l'amministratore del dispositivo è attivo, e voglio cliccare solo sullo schermo. Ho inserito hardcoded in 100.100 come posizione per i clic ai fini di questa domanda, ma realisticamente farò clic nell'angolo in basso a destra dello schermo in modo da poter premere il pulsante.

Non si verificano eventi di clic sullo schermo. Qualcuno ha esperienza con questo? Ci sono alternative per fare ciò che voglio fare? Dalla mia comprensione ci sono pochissimi strumenti che fanno questo.

Grazie.

Aggiornamento Aggiunto setSource per risposta giusta

+0

Penso che si dovrebbe togliere il setSource() chiama che si è modificato. La domanda iniziale dovrebbe dimostrare il problema, in cui la risposta mostra la soluzione. Così com'è, confrontando le due cause di confusione poiché entrambi funzionano. – Project

risposta

6

finalmente capito questo fuori. Ho confrontato i miei MotionEvents con i due eventi che sono stati inviati quando ho fatto clic su un pulsante e l'unica differenza era la fonte. Quindi, ho impostato la fonte sui due MotionEvents e ha funzionato.

.... 
motionDown.setSource(InputDevice.SOURCE_TOUCHSCREEN); 
.... 
motionUp.setSource(InputDevice.SOURCE_TOUCHSCREEN); 

Ed ecco una versione completa del metodo

//========================================================================= 
//==      Utility Methods        === 
//========================================================================= 
/** 
* Helper method injects a click event at a point on the active screen via the UiAutomation object. 
* @param x the x position on the screen to inject the click event 
* @param y the y position on the screen to inject the click event 
* @param automation a UiAutomation object rtreived through the current Instrumentation 
*/ 
static void injectClickEvent(float x, float y, UiAutomation automation){ 
    //A MotionEvent is a type of InputEvent. 
    //The event time must be the current uptime. 
    final long eventTime = SystemClock.uptimeMillis(); 

    //A typical click event triggered by a user click on the touchscreen creates two MotionEvents, 
    //first one with the action KeyEvent.ACTION_DOWN and the 2nd with the action KeyEvent.ACTION_UP 
    MotionEvent motionDown = MotionEvent.obtain(eventTime, eventTime, KeyEvent.ACTION_DOWN, 
      x, y, 0); 
    //We must set the source of the MotionEvent or the click doesn't work. 
    motionDown.setSource(InputDevice.SOURCE_TOUCHSCREEN); 
    automation.injectInputEvent(motionDown, true); 
    MotionEvent motionUp = MotionEvent.obtain(eventTime, eventTime, KeyEvent.ACTION_UP, 
      x, y, 0); 
    motionUp.setSource(InputDevice.SOURCE_TOUCHSCREEN); 
    automation.injectInputEvent(motionUp, true); 
    //Recycle our events back to the system pool. 
    motionUp.recycle(); 
    motionDown.recycle(); 
} 
+0

I love your javadoc e commenti – David

+0

@David Grazie amico! – jargetz