【问题标题】:Android Espresso Drag And Drop error Injecting eventsAndroid Espresso拖放错误注入事件
【发布时间】:2017-04-06 20:34:11
【问题描述】:

我一整天都在处理这个问题。问题是当我尝试在 Instrumental Espresso 测试中拖动某些东西时出现以下错误。

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

当我调用这个方法时会发生这种情况

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

自定义方法

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

        };

    }

swipeLinaer 取自 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;
    }

问题是这不起作用只有在触摸时设置了监听器

这样

    anyView.setOnTouchListener(new MyTouchListener());

所以设置什么样的监听器真的无关紧要,但设置的事实会导致错误。

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

我不知道如何解决这个问题。

如果有任何帮助或建议,我将不胜感激。

【问题讨论】:

    标签: java android android-espresso android-testing


    【解决方案1】:

    Android 管理滑动对象的方式不是很清楚。 当您尝试拖动某物时,Android 会生成该物的图片,该图片会跟随您的手指并让您产生拖动的想法。 问题是产生这种效果的系统组件不是来自您的应用程序,而是来自另一个应用程序,因此 Android 认为在拖动过程中您正在触摸另一个“应用程序”。 不小心触摸系统键盘也会出现同样的问题。

    解决方案是使用系统证书签署您的 apk,并在您的清单上添加 INJECT_EVENTS 权限。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-28
      • 1970-01-01
      • 2016-11-29
      • 2020-09-07
      • 2015-03-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多