Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inject input events into own application on Android?

Tags:

android

I look for a way how to inject input events such as touch or keyboard events into the own application, from code within that particular app. NOT into an Android OS or to other apps b/c that needs a signature-level permission android.permission.INJECT_EVENTS or rooted device and I have to avoid both. I look for a code that runs on a non-rooted device without anyhow elevated rights.

I'm somehow making a bit of progress with code based on the following concept:

View v = findViewById(android.R.id.content).getRootView();
v.dispatchTouchEvent(e);
like image 528
Ales Teska Avatar asked Nov 09 '22 06:11

Ales Teska


1 Answers

I think getRootView and dispatch it should works well, if there is any problem with it. Please just brief it.

Or there is an more high level but tricky way to do this. in View.java, there is a hide api called getViewRootImpl() which will return a object of android.view.ViewRootImpl of this Activity. And there is a method called enqueueInputEvent(InputEvent event) on it. So that you can use reflection to get this method.

As I have just finished a project which using Keyboard to send touch commands to the screen, I think when you are trying to inject these kind of events to the activity, multiple touch might be a problem. When you try to send another finger to the screen. The event action must be ACTION_POINTER_DOWN with the index shift of the array named properties. And you should also handle the properties and coordses arrays which including the info of all the fingers each time, even if you just need to move only one finger at this time. The finger's id which is set to properties[i].id is used to identify your finger. But the index of the array is not solid.

        for (int i = 0; i < size; i++) {
            properties[i].id = fingerId;
            properties[i].toolType = MotionEvent.TOOL_TYPE_FINGER;

            coordses[i].x = currentX;
            coordses[i].y = currentY;
            coordses[i].pressure = 1;
            coordses[i].size = DEFAULT_SIZE;
        }
        event = MotionEvent.obtain(
                    mDownTime, SystemClock.uptimeMillis(),
                    ((size - 1) << MotionEvent.ACTION_POINTER_INDEX_SHIFT)
                            + MotionEvent.ACTION_POINTER_DOWN,
                    size,
                    properties, coordses, DEFAULT_META_STATE, DEFAULT_BUTTON_STATE,
                    DEFAULT_PRECISION_X, DEFAULT_PRECISION_Y, DEFAULT_DEVICE_ID,
                    DEFAULT_EDGE_FLAGS, InputDevice.SOURCE_TOUCHSCREEN, DEFAULT_FLAGS);
like image 71
Sheldon Xia Avatar answered Nov 15 '22 05:11

Sheldon Xia