Come generare il gesto zoom / pizzico per il test per Android

Sto provando a generare il gesto zoom / pizzico per il test, ho cercato di utilizzare l'API Android MotionEvent.obtain (), ma ho trovato che è difficile implementare gli events zoom / pizzicamento.

Ho fatto riferimento all'API da MotionEvent.obtain . Puoi dirmi il metodo corretto?

  • REQUEST_DENIED con chiave browser del browser Google Places o chiave app?
  • Modo alternativo per la comunicazione tra WebView e nativo
  • Errori che gestiscono il ciclo di vita di UnityPlayer in un'applicazione Android
  • Qualsiasi editor di text ricco di risorse per Android?
  • Android - SQLite + SharedPreferences, 2 thread di lettura / scrittura contemporanea?
  • Utilizzando GCM per submit notifiche sull'app, restituisce l'errore InvalidRegistration
  • Ecco la mia implementazione:

    //for zoom, we need four points coordinations: start0, start1, end0, end1 Instrumentation inst; // action down event MotionEvent event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, 1, prop_start0, pointerCoords_start0, 0, 0, 0, 0, 0, 0, 0, 0 ); inst.sendPointerSync(event); // action pointer 2 down event event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_POINTER_2_DOWN, 2, properties_start0_1, pointerCoords_start0_1, 0, 0, 0, 0, 0, 0, 0, 0); inst.sendPointerSync(event); // action move events duration = 1000; //1000 ms event_interval = 10;//time interval between consecutive events 10ms moveEventNum = duration / event_interval; stepx0 = (end0.x - start0.x)/moveEventNum; stepy0 = (end0.y - start0.y)/moveEventNum; stepx1 = (end1.x - start1.x)/moveEventNum; stepy1 = (end1.y - start1.y)/moveEventNum; move_event0= start0; move_event1 = start1; for ( int i = 0; i < moveEventNum; i++) { // [generate middle points here ] mov_event0.x += stepx0; mov_event0.y += stepy0; mov_event1.x += stepx1; mov_event1.y += stepy1; eventTime += event_interval; event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, 2, properties_move_event, pointerCoords_move_event0_1, 0, 0, 0, 0, 0, 0, 0, 0); inst.sendPointerSync(event); } event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_POINTER_2_UP, 2, properties_end0_1, pointerCoords_end0_1, 0, 0, 0, 0, 0, 0, 0, 0); inst.sendPointerSync(event); event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, 1, end1, pointerCoords_end1, 0, 0, 0, 0, 0, 0, 0, 0 ); inst.sendPointerSync(event); 

  • Android Wear Error ConnectionResult {statusCode = SERVICE_VERSION_UPDATE_REQUIRED, risoluzione = null}
  • Come faccio a sapere se la mia applicazione è in esecuzione con Robolectric?
  • Finestra di sovrapposizione di sistema di Android
  • I frammenti ViewPager non vengono avviati in onCreate
  • Dettagli del master utilizzando ContentResolver.applyBatch ()?
  • ActionBarCompat: nasconde ActionBar prima dell'attività creata (bug?)
  • 2 Solutions collect form web for “Come generare il gesto zoom / pizzico per il test per Android”

    beh, ho trovato la questione.

    PROBLEMA:

    Quando si utilizza l'API get (), dobbiamo impostare la pressione e la dimensione dei punti in each evento.

    Per

     obtain(long, long, int, int, android.view.MotionEvent.PointerProperties[], android.view.MotionEvent.PointerCoords[], int, int, float, float, int, int, int, int) 

    le PointerCoords [], dobbiamo impostare la pressione e la dimensione su 1, i valori predefiniti sono 0.

    Per

     public static MotionEvent obtain (long downTime, long eventTime, int action, float x, float y, int metaState) Create a new MotionEvent, filling in a subset of the basic motion values. Those not specified here are: device id (always 0), pressure and size (always 1), x and y precision (always 1), and edgeFlags (always 0). since the default pressure and size are 1, so we don't need to set them. 

    I miei suggerimenti per creare gesti:

    1. seguendo la sequenza reale del gesto, dal momento che vogliamo simulare i gesti reali

    • sovrascrivere l'onTouchEvent () per controllare gli events reali ricevuti dall'applicazione. Questi events possono essere utilizzati anche per il confronto di events reali di contatto utente e gli events di contatto generati. Ad esempio:

      a) @Override boolean pubblico onTouchEvent (evento MotionEvent) {Log.i ("WebView", event.toString () + event.getAction ()); boolean rt = super.onTouchEvent (evento); return rt; }

    • schermo a sfioramento manuale per get la sequenza reale di gesti su onTouchEvent () in a). Possiamo seguire la sequenza degli events durante la generazione di events. – Se non seguiamo la sequenza di events di gesto, gli events strumentati possono essere rifiutati.

    • Ecco una sequenza di events valida di gesto dello zoom (il downTime è lo stesso per tutti gli events)

      io. ACTION_DOWN di un punto di partenza

      ii. ACTION_POINTER_2_DOWN di due punti di partenza

      iii.ACTION_MOVE di due punti medi

      iv. ACTION_POINTER_2_UP di due punti finali

      v. ACTION_UP di un punto finale

    2. utilizzare correttamente la API MotionEvent.obtain

    • Ci sono due API get () più utilizzati.

    il MotionEvent statico pubblico ottiene (lungo tempo di fermo, tempo lungo di tempo, azione int, float x, float y, int metaState)

    E

    (int, int, float, float, int, int, int, int), static MotionEvent statico get (lungo, lungo, int, int, android.view.MotionEvent.PointerProperties [], android.view.MotionEvent.PointerCoords [

    Il primo è di solito utilizzato per gesti a singolo punto, come il lancio, il scroll, il clic ecc. I parametri (pressione, dimensione, xPresione, yPresione) di questa function sono tutti impostati su 1.

    E il secondo è più generale, e può essere utilizzato per generazioni di events multi-touch. Mentre per il secondo, dobbiamo impostare la pressione, la dimensione in pointerCoords di each punto di touch su 1.

    Ecco l'esempio per generare il gesto di zoom:

     public static void generateZoomGesture(Instrumentation inst, long startTime, boolean ifMove, GestureInfo.Point startPoint1, GestureInfo.Point startPoint2, GestureInfo.Point endPoint1, GestureInfo.Point endPoint2, int duration) { if (inst == null || startPoint1 == null || (ifMove && endPoint1 == null)) { return; } long eventTime = startTime; long downTime = startTime; MotionEvent event; float eventX1, eventY1, eventX2, eventY2; eventX1 = startPoint1.x; eventY1 = startPoint1.y; eventX2 = startPoint2.x; eventY2 = startPoint2.y; // specify the property for the two touch points PointerProperties[] properties = new PointerProperties[2]; PointerProperties pp1 = new PointerProperties(); pp1.id = 0; pp1.toolType = MotionEvent.TOOL_TYPE_FINGER; PointerProperties pp2 = new PointerProperties(); pp2.id = 1; pp2.toolType = MotionEvent.TOOL_TYPE_FINGER; properties[0] = pp1; properties[1] = pp2; //specify the coordinations of the two touch points //NOTE: you MUST set the pressure and size value, or it doesn't work PointerCoords[] pointerCoords = new PointerCoords[2]; PointerCoords pc1 = new PointerCoords(); pc1.x = eventX1; pc1.y = eventY1; pc1.pressure = 1; pc1.size = 1; PointerCoords pc2 = new PointerCoords(); pc2.x = eventX2; pc2.y = eventY2; pc2.pressure = 1; pc2.size = 1; pointerCoords[0] = pc1; pointerCoords[1] = pc2; ////////////////////////////////////////////////////////////// // events sequence of zoom gesture // 1. send ACTION_DOWN event of one start point // 2. send ACTION_POINTER_2_DOWN of two start points // 3. send ACTION_MOVE of two middle points // 4. repeat step 3 with updated middle points (x,y), // until reach the end points // 5. send ACTION_POINTER_2_UP of two end points // 6. send ACTION_UP of one end point ////////////////////////////////////////////////////////////// // step 1 event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, 1, properties, pointerCoords, 0, 0, 1, 1, 0, 0, 0, 0 ); inst.sendPointerSync(event); //step 2 event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_POINTER_2_DOWN, 2, properties, pointerCoords, 0, 0, 1, 1, 0, 0, 0, 0); inst.sendPointerSync(event); //step 3, 4 if (ifMove) { int moveEventNumber = 1; moveEventNumber = duration / EVENT_MIN_INTERVAL; float stepX1, stepY1, stepX2, stepY2; stepX1 = (endPoint1.x - startPoint1.x) / moveEventNumber; stepY1 = (endPoint1.y - startPoint1.y) / moveEventNumber; stepX2 = (endPoint2.x - startPoint2.x) / moveEventNumber; stepY2 = (endPoint2.y - startPoint2.y) / moveEventNumber; for (int i = 0; i < moveEventNumber; i++) { // update the move events eventTime += EVENT_MIN_INTERVAL; eventX1 += stepX1; eventY1 += stepY1; eventX2 += stepX2; eventY2 += stepY2; pc1.x = eventX1; pc1.y = eventY1; pc2.x = eventX2; pc2.y = eventY2; pointerCoords[0] = pc1; pointerCoords[1] = pc2; event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, 2, properties, pointerCoords, 0, 0, 1, 1, 0, 0, 0, 0); inst.sendPointerSync(event); } } //step 5 pc1.x = endPoint1.x; pc1.y = endPoint1.y; pc2.x = endPoint2.x; pc2.y = endPoint2.y; pointerCoords[0] = pc1; pointerCoords[1] = pc2; eventTime += EVENT_MIN_INTERVAL; event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_POINTER_2_UP, 2, properties, pointerCoords, 0, 0, 1, 1, 0, 0, 0, 0); inst.sendPointerSync(event); // step 6 eventTime += EVENT_MIN_INTERVAL; event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, 1, properties, pointerCoords, 0, 0, 1, 1, 0, 0, 0, 0 ); inst.sendPointerSync(event); } 

    Per fare funzionare il codice precedente con costanti non deprecate ho usato MotionEvent.ACTION_POINTER_DOWN + (pp2.id << MotionEvent.ACTION_POINTER_INDEX_SHIFT) anziché MotionEvent.ACTION_POINTER_2_DOWN

    Quindi ho dovuto sostituire questa linea:

    event = MotionEvent.obtain (downTime, eventTime, MotionEvent.ACTION_POINTER_2_DOWN, 2, properties;, pointerCoords, 0, 0, 1, 1, 0, 0, 0, 0);

    con

    evento = MotionEvent.obtain (downTime, eventTime, MotionEvent.ACTION_POINTER_DOWN + (pp2.id << MotionEvent.ACTION_POINTER_INDEX_SHIFT), 2, properties;, pointerCoords, 0, 0, 1, 1, 0, 0, 0, 0);

    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.