2017-03-04 3 views
1

Ich habe mich mit diesem Problem einen ganzen Tag beschäftigt. Das Problem ist, dass ich den folgenden Fehler bekomme, wenn ich versuche, etwas in meinen Instrumental Espresso Tests zu ziehen.Androider Espresso Drag and Drop Fehler Einspritzen von Ereignissen

Caused by: android.support.test.espresso.InjectEventSecurityException: java.lang.SecurityException: Injecting to another application requires INJECT_EVENTS permission 

Dies geschieht, wenn ich diese Methode aufrufen

onView(withId(R.id.any_id)).perform(CustomViewActions.touchAndDrag(200, 200)); 

Benutzerdefinierte Methode

public static ViewAction touchAndDrag(final float x, final float y, final long delay) { 
     return new ViewAction() { 

      @Override 
      public void perform(UiController uiController, final View view) { 
       // Get view absolute position 
       sendLinearSwipe(uiController,coordinatesClickOn,coordinatesMoveTo,precision,2000); 

     }; 

    } 

Und swipeLinaer aus den Quellen von Espresso

private static Swiper.Status sendLinearSwipe(UiController uiController, float[] startCoordinates, 
               float[] endCoordinates, float[] precision, int duration) { 
     checkNotNull(uiController); 
     checkNotNull(startCoordinates); 
     checkNotNull(endCoordinates); 
     checkNotNull(precision); 

     float[][] steps = interpolate(startCoordinates, endCoordinates, SWIPE_EVENT_COUNT); 
     final int delayBetweenMovements = duration/steps.length; 

     MotionEvent downEvent = MotionEvents.sendDown(uiController, startCoordinates, precision).down; 
     try { 
      for (int i = 0; i < steps.length; i++) { 
       if (!MotionEvents.sendMovement(uiController, downEvent, steps[i])) { 
        Log.e(TAG, "Injection of move event as part of the swipe failed. Sending cancel event."); 
        MotionEvents.sendCancel(uiController, downEvent); 
        return Swiper.Status.FAILURE; 
       } 

       long desiredTime = downEvent.getDownTime() + delayBetweenMovements * i; 
       long timeUntilDesired = desiredTime - SystemClock.uptimeMillis(); 
       if (timeUntilDesired > 10) { 
        uiController.loopMainThreadForAtLeast(timeUntilDesired); 
       } 
      } 

      if (!MotionEvents.sendUp(uiController, downEvent, endCoordinates)) { 
       Log.e(TAG, "Injection of up event as part of the swipe failed. Sending cancel event."); 
       MotionEvents.sendCancel(uiController, downEvent); 
       return Swiper.Status.FAILURE; 
      } 
     } finally { 
      downEvent.recycle(); 
     } 
     return Swiper.Status.SUCCESS; 
    } 

Das Problem genommen wurde, ist th auf das nicht funktioniert, NUR WENN TOUCH Zuhörer

eingestellt ist, dass wie

anyView.setOnTouchListener(new MyTouchListener()); 

es also wirklich keine Rolle, welche Art von Hörer gesetzt ist, aber die Tatsache, es gesetzt wird, bewirkt die Fehler .

private final class MyTouchListener implements View.OnTouchListener { 
     public boolean onTouch(View view, MotionEvent motionEvent) { 
      if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { 
       ClipData data = ClipData.newPlainText("", ""); 
       View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(
         view); 
       view.startDrag(data, shadowBuilder, view, 0); 
       view.setVisibility(View.INVISIBLE); 
       return true; 
      } else { 
       return false; 
      } 
     } 
    } 

Ich habe keine Ahnung, wie Sie dieses Problem lösen.

würde ich für jede Hilfe oder Rat dankbar.

Antwort

0

Die Art und Weise Android verwalten Objekt klauen ist nicht so klar. Wenn Sie versuchen, etwas zu ziehen, generieren Android ein Bild von dem Ding, das Ihrem Finger folgt und Ihnen die Idee des Ziehens gibt. Das Problem ist, dass die Komponente des Systems, die diesen Effekt erzeugt, nicht von Ihrer Anwendung kommt, sondern von einer anderen App und so glaubt Android, dass Sie während des Ziehens eine andere "App" berühren. Das gleiche Problem tritt auf, wenn Sie versehentlich die Systemtastatur berühren.

Die Lösung ist Ihr apk mit System-Zertifikat signieren und INJECT_EVENTS Erlaubnis auf Ihrem Manifest hinzufügen.