Accessing event input nodes in Android withour rooting
Asked Answered
N

1

0

I want to be able to inject different events into an Android device. After some search, I found that I can do this by accessing event input nodes in Android OS, which are found in dev/input/eventX. Once these are accessed, read and write operations can take place, and hence I can inject events.

The problem is that these nodes are only accessible in a rooted device. If I try to use them without rooting, the process will fail as mentioned in this article,

http://www.pocketmagic.net/programmatically-injecting-events-on-android-part-2/

I don't want to root the device to preserve its warranty. I've searched the web for possible ways to accessing Android OS, but I only found rooting.

The alternative way which I think it would work is compiling the application as a system application, but I couldn't found whether this will allow it to have access (both read and write privileges) to event input nodes. Will this method provide these privileges?

If not, is there any alternative way to rooting, where I can give system permissions to my application without rooting the device?

Any help is appreciated.

Thanks.

EDIT: To elaborate more, I want to inject different touch events. For example, single touch, swipe, etc.

Nilsanilsen answered 30/10, 2015 at 18:27 Comment(0)
F
1

You can inject input events on a device by executing the /system/bin/input utility that ships with Android. You can see some examples of it being used (via adb) in this question. The input utility does not appear to need any special privileges to execute.

To create a system application, you need access to the signing keys used when the Android OS for your device was built - you can't just modify an ordinary App to give it system privileges. Even if you could, it wouldn't give you root access (although you could probably make it part of the input user group which the /dev/input/eventX devices also appear to allow access to).

If you want to inject touch events, you can either execute the /system/bin/input utility using the exec() method of the Java Runtime class or just use the injectMotionEvent() method in InputManager.

Below is a method taken from the Android source showing how to inject a MotionEvent - you can view the full source for more info.

/**
     * Builds a MotionEvent and injects it into the event stream.
     *
     * @param inputSource the InputDevice.SOURCE_* sending the input event
     * @param action the MotionEvent.ACTION_* for the event
     * @param when the value of SystemClock.uptimeMillis() at which the event happened
     * @param x x coordinate of event
     * @param y y coordinate of event
     * @param pressure pressure of event
     */
    private void injectMotionEvent(int inputSource, int action, long when, float x, float y, float pressure) {
        final float DEFAULT_SIZE = 1.0f;
        final int DEFAULT_META_STATE = 0;
        final float DEFAULT_PRECISION_X = 1.0f;
        final float DEFAULT_PRECISION_Y = 1.0f;
        final int DEFAULT_DEVICE_ID = 0;
        final int DEFAULT_EDGE_FLAGS = 0;
        MotionEvent event = MotionEvent.obtain(when, when, action, x, y, pressure, DEFAULT_SIZE,
                DEFAULT_META_STATE, DEFAULT_PRECISION_X, DEFAULT_PRECISION_Y, DEFAULT_DEVICE_ID,
                DEFAULT_EDGE_FLAGS);
        event.setSource(inputSource);
        Log.i(TAG, "injectMotionEvent: " + event);
        InputManager.getInstance().injectInputEvent(event,
                InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
    }

These methods only allow you to inject events into your own app windows.

If you want to inject events into other windows not owned by your app, you need to declare additional permissions (READ_INPUT_STATE and INJECT_EVENTS) in your app manifest and sign your App with the Android OS signing keys. In other words, the permissions needed to inject events into other apps are never granted to ordinary apps (for obvious reasons).

Fromma answered 30/10, 2015 at 18:57 Comment(3)
thanks a lot for providing this useful answer, please check the question regarding the event type, I've updated it. I want the app that I will build to be able to inject the touch events, so is this possible via /system/bin/input? Or, do I need to connect it to a computer and send the commands from there? Also, can you please tell me how to make my app as a part of input user group? Thank you.Nilsanilsen
thanks a lot for your answer, so just to make sure, if I used the permissions you provided in the mainfest file, sign my app with Android signing keys, then my app will be able to inject touches throughout the system in any window, right? Let's say that I want to open another app at x and y coordinates on the screen, then having the permissions and the signing keys, I can do that through my app without rooting, right? Please let me know. Thanks a lot.Nilsanilsen
@Nilsanilsen I'm not sure what you mean by open another app at x and y coordinates - If you want to launch another app, you should just use startActivity() with an appropriate intent. In any case, according to the source, the INJECT_EVENTS permission allows you to send input events to any window. I've never used it, so I can't give you a definite answer - like most programming features, the easiest way is not to ask people, but to try it out and see for yourself.Fromma

© 2022 - 2024 — McMap. All rights reserved.