简体   繁体   中英

Invoke touch event on screen at particular x, y location

Working on the functionality similar to the EVA Facial Mouse , I need to trigger the touch even on the screen at location x, y on the device.

I tried dispatching event on the root view but it doesn't work. It works when I have a particular view to dispatch the event but in my case, I will not be having the view in focus at runtime. I also tried invoking input event from the window but this also did not help.

Can anyone suggest a way through which I can trigger the event on the screen that my views can listen?

With the reference from this discussion . Below defined function seems to do the trick for me:

@SuppressLint("PrivateApi")
    public void createTouch(float x, float y) {
        String methodName = "getInstance";
        Object[] objArr = new Object[0];
        InputManager im = null;
        try {
            im = (InputManager) InputManager.class.getDeclaredMethod(methodName, new Class[0])
                    .invoke(null, objArr);
        } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            e.printStackTrace();
        }

        //Make MotionEvent.obtain() method accessible
        methodName = "obtain";
        try {
            //noinspection RedundantArrayCreation
            MotionEvent.class.getDeclaredMethod(methodName, new Class[0]).setAccessible(true);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

        //Get the reference to injectInputEvent method
        methodName = "injectInputEvent";
        Method injectInputEventMethod = null;
        try {
            //noinspection RedundantArrayCreation
            injectInputEventMethod = InputManager.class
                    .getMethod(methodName, new Class[]{InputEvent.class, Integer.TYPE});
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

        long when = SystemClock.uptimeMillis();
        int source = InputDeviceCompat.SOURCE_TOUCHSCREEN;
        float pressure = 1.0f;
        int action = 0;
        @SuppressLint("Recycle")
        MotionEvent event = MotionEvent.obtain(when, when, action, x, y, pressure,
                1.0f, 0, 1.0f, 1.0f, 0, 0);
        event.setSource(source);
        try {
            assert injectInputEventMethod != null;
            //noinspection RedundantArrayCreation,UnnecessaryBoxing
            injectInputEventMethod.invoke(im, new Object[]{event, Integer.valueOf(0)});
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM