Programmatically Injecting Events on Android – Part 1

Note: Part two on programmatically injecting events on Android has been published and is available here.

The successful Android platform has been around for a few years now. End users get lots of bells and whistles in fancy applications, but for developers, this "open-intended" platform seems even more tangled up than ever.
There are various APIs that still do not work, others that get deprecated-and-out in a single release, or some that are locked up for the supreme security purpose, invoked so very often by platform developers, that probably feel they've given the right answer.
All in one, Android also comes with a lot of frustration, because tools that are needed to accomplish various tasks or even more advanced applications, are put behind bars on purpose.

Another example of many is injecting a key press programmatically or the similar counter-part, injecting a touch event (mouse).
Because a malicious programmer might develop a software that would open your Market app and download payed apps without you knowing about it, developers world wide are prohibited from sending a key press programmatically to other applications except their own.

This is just ridiculous narrow thinking.

Of course there will always be a balance between security and functionality, but with paranoia it quickly turns to total failure. In other words why limit something so useful that can create so little damage? Users are warned about risks with normal permissions and it should stay that way for other features as well.

I'll just leave them with their issues and get back to the topic: I am aware of three methods for injecting events programmatically. This refers both to keyboard events (keys) and mouse events (touch events).

Method 1: Using internal APIs

This approach has its risks, like it is always with internal, unpublished APIs.
The idea is to get an instance of WindowManager in order to access the injectKeyEvent / injectPointerEvent methods.

  1.  
  2. IBinder wmbinder = ServiceManager.getService( "window" );
  3. IWindowManager m_WndManager = IWindowManager.Stub.asInterface( wmbinder );
  4.  

The ServiceManager and WindowsManager are defined as Stubs. We can then bind to these services and call the methods we need. The interfaces are included in the sample code attached at the end of this article.

To send a key do the following:

  1.  
  2. // key down
  3. m_WndManager.injectKeyEvent( new KeyEvent( KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A ),true );
  4. // key up
  5. m_WndManager.injectKeyEvent( new KeyEvent( KeyEvent.ACTION_UP, KeyEvent.KEYCODE_A ),true );
  6.  

To send touch/mouse events use:

  1.  
  2. //pozx goes from 0 to SCREEN WIDTH , pozy goes from 0 to SCREEN HEIGHT
  3. m_WndManager.injectPointerEvent(MotionEvent.obtain(SystemClock.uptimeMillis(),
  4. SystemClock.uptimeMillis(),MotionEvent.ACTION_DOWN,pozx, pozy, 0), true);
  5. m_WndManager.injectPointerEvent(MotionEvent.obtain(SystemClock.uptimeMillis(),
  6. SystemClock.uptimeMillis(),MotionEvent.ACTION_UP,pozx, pozy, 0), true);
  7.  

This works fine, but only inside your application

The moment you're trying to inject keys/touch events to any other window, you'll get a force close because of the following exception:

  1.  
  2. E/AndroidRuntime(4908): java.lang.SecurityException: Injecting to another application requires INJECT_EVENTS permission
  3.  

Not much joy, as INJECT_EVENTS is a system permission. A possible solution is discussed here and here.

Method 2: Using an instrumentation object

This is a clean solution based on public API, but unfortunately it still requires that INJECT_EVENTS permission.

  1.  
  2. Instrumentation m_Instrumentation = new Instrumentation();
  3. m_Instrumentation.sendKeyDownUpSync( KeyEvent.KEYCODE_B );
  4.  

For touch events you can use:

  1.  
  2. //pozx goes from 0 to SCREEN WIDTH , pozy goes from 0 to SCREEN HEIGHT
  3. m_Instrumentation.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(),
  4. SystemClock.uptimeMillis(),MotionEvent.ACTION_DOWN,pozx, pozy, 0);
  5. m_Instrumentation.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(),
  6. SystemClock.uptimeMillis(),MotionEvent.ACTION_UP,pozx, pozy, 0);
  7.  


All good inside the test application, and will crash instantly when trying to inject keys to outside apps, not because the approach doesn't work, but because Android Developers have chosen so. Thanks guys, you rock! Not.
By looking at sendPointerSync's code, you will quickly see it uses the same approach as presented in method 1). So this is the same thing, but packed nicely in a easy to use API:

  1.  
  2. public void sendPointerSync(MotionEvent event) {
  3. validateNotAppThread();
  4. try {
  5. (IWindowManager.Stub.asInterface(ServiceManager.getService("window")))
  6. .injectPointerEvent(event, true);
  7. } catch (RemoteException e) {
  8. }
  9. }
  10.  

Method 3: Direct event injection to /dev/input/eventX

Linux exposes a uniform input event interface for each device as /dev/input/eventX where X is an integer. We can use it directly and skip the above Android Platform permission issues.
For this to work, we will need root access, so this approach only works on a rooted device.
I felt it was easier to deal with linux using native C code, but a pure java implementation is also possible. Therefore I have added a small JNI component to handle the interface with /dev/input/eventX.

The sample code I wrote doesn't detect the X number automatically, so make sure you set that before running the code. By default I set it to event3. You can change that in NativeInput.java, see code below.

As I said, this last method requires root. By default the eventX files have the permission set for 660 (read and write for Owner and Group only). To inject keys from our application, we need to make it writable. So do this first:

  1.  
  2. adb shell
  3. su
  4. chmod 666 /dev/input/event3
  5.  

You will need root to run the chmod command.

Sample Code

AndroidKeyInjector

Other great resources:

Generating keypresses programmatically
Internal input event handling in the Linux kernel and the Android userspace
androidscreencast

Note: Part two has been published and is available here.

Related Post

This article has 100 Comments

  1. Hey Radu

    Thx for the nice little demo.

    I cant get method 3 to work on my sgs2 with android 4.03. I installed your demo application and chanced it to method 3. When it was installe I did adb shell su chmod 666 /dev/input/event3 but nothing happens when i pres start.

    Logcat says:
    5-30 10:21:38.642: D/dalvikvm(19464): Late-enabling CheckJNI
    05-30 10:21:38.657: I/dalvikvm(19464): Turning on JNI app bug workarounds for target SDK version 5…
    05-30 10:21:38.662: D/dalvikvm(19464): Debugger has detached; object registry had 1 entries
    05-30 10:21:38.737: D/dalvikvm(19464): Trying to load lib /data/data/net.pocketmagic.keyinjector/lib/libinput.so 0x41507800
    05-30 10:21:38.742: D/dalvikvm(19464): Added shared lib /data/data/net.pocketmagic.keyinjector/lib/libinput.so 0x41507800
    05-30 10:21:38.747: D/JNI(19464): Debug enabled.
    05-30 10:21:38.747: D/JNI(19464): intCreate call (/dev/input/event3)
    05-30 10:21:38.747: D/JNI(19464): intCreate success: 44
    05-30 10:21:38.902: D/CLIPBOARD(19464): Hide Clipboard dialog at Starting input: finished by someone else… !
    05-30 10:21:56.802: D/AKI(19464): Inject method:3
    05-30 10:21:56.802: D/JNI(19464): intSendEvent call (44,1,46,1)
    05-30 10:21:56.802: D/JNI(19464): intSendEvent done:16
    05-30 10:21:56.802: D/JNI(19464): intSendEvent call (44,1,46,0)
    05-30 10:21:56.802: D/JNI(19464): intSendEvent done:16
    05-30 10:21:57.802: D/AKI(19464): Inject method:3
    05-30 10:21:57.802: D/JNI(19464): intSendEvent call (44,1,46,1)
    05-30 10:21:57.802: D/JNI(19464): intSendEvent done:16
    05-30 10:21:57.802: D/JNI(19464): intSendEvent call (44,1,46,0)
    05-30 10:21:57.802: D/JNI(19464): intSendEvent done:16
    05-30 10:22:36.947: D/dalvikvm(19464): Debugger has detached; object registry had 1 entries

    Can you se what im doing wrong here?

  2. Hi,
    step1 My device(Motorola Xoom 3.2) is rooted.and following below steps to perform keyInject at any Pixel on device
    step–1(a) Set event3 chmod to 777
    (b) Running below Code in a background thread.
    m_ni.SendKey(46 , true);
    m_ni.SendKey(46, false);
    step–2 To check key Event create another application with no title-bar and having A single button with OnClickListener. when the button is clicked it will display a Toast.
    step -3 Launch 1st step App and then 2nd step App

    but nothing is happening neither it display any Exception nor it display the toast.
    please help!!!!!!

  3. Thanks for a great explanaition + example!
    I ran your code and methode 1 and 2 work like you explained, but I can’t get methode 3 to work..
    Any tips?
    Thanks in advance!

  4. @Radu:
    in 4.1 4.2
    IWindowManager have changed there is no inject* method ever.

    But we can use KeyEvent home = new KeyEvent(KeyEvent.ACTION_DOWN,
    KeyEvent.KEYCODE_HOME);
    InputManager.getInstance().injectInputEvent(home,
    InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);

  5. in 4.1 4.2
    we should do like below:

    KeyEvent home = new KeyEvent(KeyEvent.ACTION_DOWN,
    KeyEvent.KEYCODE_HOME);
    InputManager.getInstance().injectInputEvent(home,
    InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);

  6. @insomnia: I didn’t have the chance to test that yet, but it wouldn’t be something new for google to break previous android functionality with each new release.

  7. Hello there Radu

    First of all congratz on your excellent work on this post and the CursorOverlay post.

    My needs are the same as many, I need to make a Mouse Cursor to control the entire OS. My research lab has develop a system that translate Tongue movements into commands, and now we want to make it compatible with Android. Following your example CursorOverlay app I was able to make a perfect translation from the Tongue Input Device to the cursor, to move the cursor anywhere on the screen(THANK!). However I am stuck at the clicking (inject touch event).

    I applied Method 1 & 2 and confirmed they cursor works inside the Service App, however I get the security INJECT_EVENT error as you stated. I followed the recommendations of others to install the app at the system level but that did not help, since its a signature issue not a system permission. So my only option is Method 3, which I don’t understand with my lack of Linux background. So is it possible for you to guide me on how to achieve this. How to determine which event# is the current one for me or how to use your NativeInput class to make it work on my Service app.

    This app will lead to a great innovation for people that really need this. Feel free to contact me at my email.

    Phone: Galaxy S2 (SGH-T989)
    OS: 4.0.3

  8. That’s a new way of controlling a mobile device with one’s tongue. I’ve seen your devices mounted inside one’s mouth – impressive idea. I will get back to you by email for your questions.

  9. Hi Radu, thank you for both your Android Cursor Overlay and Android Injecting Events Programmatically tutorials. I was really helped by your tutorials to finish my thesis. But I encounter a problem similar to Abner’s. I would like to create a mouse cursor that can be controlled by user and imitate the touch event.

    Unfortunately, I don’t know how to do it with your 3rd method. I successfully tried the first and second method. But the third one only produces key event, not touch. Could you help me to give instructions to inject touch event with the 3rd method?

    Because I think it’s the only way to inject touch event outside my application. I’ve tried the 1st and 2nd event with system permission (INJECT_EVENTS permission and install in /system/app/) and Android platform key signing, but it doesn’t work. It won’t install because the key is different from the platform I used.

    My device is Samsung Galaxy S2 (GT-I9100) Rooted with SpeedMod ICS 4.0.4. I really appreciate your help. Thank you.

  10. @Mike, I’ve been working on a library to implement method #3 including touch events, and input event node detection, as an attempt to help Abner, but also others interested on this perfectly normal functionality that google excluded on purpose.

    I didn’t have time to structure a new article yet , but the library is available under GPL v2 here: http://code.google.com/p/android-event-injector/

    For rooted phones, this is a good way to go. The library also includes the chmod part for the input event nodes.

  11. Hi Radu, thank you for your quick reply 🙂 I’ll look into the library for the solution. Really appreciate your effort. Thank you, thank you very much.

  12. No problem, Michael, I try to help where possible. Just keep in mind that I still need to polish the library and also write an article on it, or at least a short wiki page.

  13. Hi Radu, thanks for the library 😀 Unfortunately I encounter an error when I build the native library (libEventInjector.so) with Android NDK using this command /ndk-build. I have errors showing that many of the constants, such as INPUT_PROP_POINTER, INPUT_PROP_DIRECT, INPUT_PROP_BUTTONPAD, etc., are undeclared. Thus, I can’t create the .so library file. Could you help me with this problem? Thank you.

  14. Yes. Did you change the OS version of my original project? If not, make sure you are using the latest NDK version (android-ndk-r8b). The errors you are getting are caused by the compiler not being able to find resources related to the project platform, in this case the linux\input.h file.

  15. I used Mac OS X for development. But I don’t think I change the OS version of your original project. The original project seems to be using Windows, correct? I’m using the latest NDK, which is android-ndk-r8c. I see. How do I include that input.h to my project?

  16. First, browse to android-ndk-r8b\platforms\ and tell me what are the platforms listed there. Next search for input.h and let me know if all the platforms contain it.

  17. ok, this is good, now go to your SDK folder and make sure you have android-8 installed: Android\android-sdk\platforms\

  18. Ah, there it is! I don’t have android-8. I’ll install it right away. Is it possible to use another platform, though?

  19. See that you can open the JAVA part of the project in eclipse and compile. I have the impression something went wrong with your Android-8 installation.

    Yes, you can change the platform, and this is another way to go, simply edit AndroidManifest.xml and project.properties.

  20. Hi Radu, thank you for your help 😀 I managed to overcome the problem. Here are the steps:
    1. Replace the input.h in the linux folder of Android NDK platform that you use, in my case it’s the android-14in android-ndk-r8c, with the more complete version of input.h file from https://github.com/quarck/csetup/blob/master/csetup/jni/input.h. The path is /platforms/android-14/arch-arm/usr/include/linux/input.h. It will clear all the errors of undeclared constants
    2. Modify the methods’ names in the native C files with your own customized project package name. In this case, it’s the “Java_net_pocketmagic_android_eventinjector_Events_METHODNAME” because the file is located in package net.pocketmagic.android.eventinjector and in Events file with respective method’s name.
    3. Make sure that the project target in project.properties file is showing one of SDK versions available in the NDK with the replaced input.h file. In my case, it’s the android-14. Just ignore the ndk-build command’s warning saying something like APP_PLATFORM is higher than the minSDK in manifest file.
    4. Run the ndk-build program in your project’s root folder. Then “obj” folder will be created containing the .so library file. It will be also available in the “libs” folder.
    5. Run the application from Eclipse just like usual. Note that, every time you make change to the native file, you must re-build the native library.

    That’s it. Your project should now work. Thank you Radu. Couldn’t do it without you.

  21. Michael, I don’t understand why some of the steps were necessary in your case (like 1 and 2), however I’m glad to see you managed to use it.

  22. Hi Radu, the first step is required because the input.h file from the NDK that I have is not somewhat complete. It doesn’t have many variables that you mentioned in the native .h file. I don’t know why either. I’ve tried with NDK 8, 8b, 8c and all produce same error result. Maybe you had modify it previously on your computer. I don’t think it’s because the OS (I us Mac), but it probably is.

    The second step is required because I copy and use it in my new project. If you only want to try to run the sample library project, you don’t need to do that 😀

    Anyway, thanks Radu.

    But there is something that I want to ask. When I “open” the touchscreen input device from your project and try to inject touch event, my original touch screen is not working anymore. I can’t touch buttons or navigate through the Android OS. The only thing to recover it is by restarting the phone. Is that intentionally, expected, and okay?

  23. @Michael, if you include this in your project, don’t forget that my code is under GPL license. Make sure you read it and understand it correctly. Normally you should include the code as it is, without changing names – this is not needed.

    Modifying the NDK files is not ok. I compiled the code without changing anything , so probably there is something wrong at your end. Double check and triple check your NDK installation to make sure the paths are ok.

    Regarding your question, I didn’t see this behavior, but I will double check when I get some time. You probably also need to close any open input event nodes after you are done with them to avoid any concurrency issues with the OS trying to access them. Just a random thought.

  24. Hi Radu, yes I include it in my project and also put your name and website links as my sources and references. Okay, then. I need to adjust some methods to fit my project. I don’t change the name of the files, though.

    Hmm, isn’t it necessary to modify the NDK files’ methods if I put your files in my package? Because the names of the packages are different, resulting different names of methods in NDK files. I’m sure the NDK installation is okay now because I can use ndk-build command in your sample project too.

    I see, thank you Radu. I tried this in both your sample project and my project, and was still having same result. I couldn’t use my touch screen anymore as soon as I injected the touch event. Don’t know why. I’m trying to figure it out now.

  25. I need to create an app that will automatically play a third party game.so the app should inject events to the game app. By third party games I mean I dont have the source code.So is it possible to inject events through an app to another app..?

  26. I am a student of computer engineering.I am creating vnc server for android.I am working on a service(running in background) that performs touch events on given coordinates. I tried running the .apk provided by you at “https://code.google.com/p/android-event-injector/” this link, on a rooted emulator made at API level-10 as a system app ,but it crashed. Please help.

  27. @shanu , you have full access to the source code, why don’t you check that error to see what exactly goes wrong?

  28. hi Radu,thankss for the quick reply !
    could you suggest me the version of android at which your app runs most efficiently

  29. Hi shanu, if I remember correctly, you can use android 2.2 or newer. But take a look at the source code posted on google-code to see the project’s target OS.

  30. hey Radu, finally the code is working on my rooted emulator. The code was crashing because there was no file as /dev/input/event3 in the emulator. There was only one file as /dev/input/event0. So, i changed the path in ur code and it started working !!! 🙂
    Also, i wanted it to perform touch on some given coordinate and i’ve successfully changed it for the same .
    Thank u soo much :D,,, Really thankxx a lot !!

  31. Sorry for a quick question, I did not test the code yet
    It is about Method 1: Using internal APIs
    You say it is able to send touch events inside our own application only
    What about the soft keyboard that pops out?
    Can we send touch events to the soft keyboard that pops out in our application without crashing?
    Thanks in advance.

  32. Sorry for a quick question, I did not test the code yet
    It is about Method 1: Using internal APIs, You say it is able to send touch events inside our own application only
    What about the soft keyboard that pops out? Let say Android stock keyboard, or Swype, or Swiftkey
    Can we send touch events to the soft keyboard that pops out in our application without crashing?
    I am not sure whether the soft keyboard is considered as the same application, or external application.
    Actually I want to send touch events to Swype keyboard, swiping across several keys to create a word.
    The inputs will come from my app, which will get the touch coordinate from front camera by detecting hand motion. (just a concept, not yet started working on it yet)
    Thanks in advance.

  33. Hi,

    Your examples are very explanatory and work very well. Thank you very much!

    I have a question about a problem that is puzzling me.

    Is there any way to supress some input events so Android does not handle them?

    The idea would be, for instance, polling a device for it’ s events and generate other transformed events injected in another device out of those (i.e. keyboard to touch). The original input device events should not be handled by android. To be honest I’m not sure if this can be done at a kernel level or if there is any way to access the configuration of android so it stops listening to events from a particular input.

  34. Hello, great post. I have a similar question as tcboy. I am trying to simulate touch gestures over the software keyboard to swipe across several keys to make a word. I am trying to use your method 2 and the below code from Robotium to interact with my app. It works fine when the keyboard in not up but when the software keyboard is up it is executed but no MotionEvent.ACTION_DOWN is registered in the app of the keyboard.

    I was able to get adb shell input tap x y to click on the key in the software keyboard but this will not work as I need more control of the specific motion actions.
    Any suggestion on how I can get suggestion 2 working on the software keyboard to press keys? Do I need to set some flag in my app layout.xml file?

    TEST CODE:

    Instrumentation inst = getInstrumentation();
    // sending event – finger touched the screen
    MotionEvent event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, xStart, yStart, 0);
    inst.sendPointerSync(event);

  35. I can’t select a valid device on the spinner.
    When I touch on the spinner, the screen is dimed and any item list is not opened.
    Isn’t getting device name permitted on my device? I can’t find what is problem..Could you give me an idea?

    my deive :
    Galaxy Note 2 / Anroid 4.1.2

  36. Hi Radu. You indicate that for type 1, “The ServiceManager and WindowsManager are defined as Stubs”, where do we get these Stubs from? it seems they are not included in the latest android releases ? Thanks.

  37. Hi Radu. You indicate that for type 1, “The ServiceManager and WindowsManager are defined as Stubs”, where do we get these Stubs from? it seems they are not included in the latest android releases ? Thanks.

  38. Hello Radu – Since injectKeyEvent is depricated and not available, do you know of any other way to inject events in same application? Method 3 does not work for me as it needs rooting. Even Method 2 does not work for me as all I know is x,y coordinates and not view details so instruments does not help.

  39. Hi Radu, is it possible to use the instrumentation only inside my app with out using the INJECT_EVENTS permission?

  40. Radu, if it it possible to use the instrumentation only inside the app without using the INJECT_EVENTS permissions, do you have an example of this ?? Thanks.

  41. @Mohamed: the source code is included with the article. For instrumentation, see below “Method 2: Using an instrumentation object”.

  42. I have played around with injecting pointer motion events but have found that teh mouse cursor will not work. Is there a way to have the mouse pointer (or ANY pointer) move with these events?

  43. Hello Radu,
    I am able to use INJECT_EVENTS permission , and i used ant to build the project.
    Now i have an app with a background service ,this service is responsible to actuate the key events, i am using Instrumentation class for this. I am able to actuate the events inside the app but I am not able to do it on global level or outside the app.
    Can u suggest me approach!!

  44. hello Rajiv,

    please see part 2 of this article. also , what do you mean by ” I am able to use INJECT_EVENTS permission” ?

  45. Hi Radu,

    I am face this error While clik on “Start” button.
    The Error is “Unfortunetly,AndroidKeyInjector has stopped”

    Please Let me know ,how to resolve this error.

    Thanks
    Mahen

  46. It has been crashed on below line .
    m_WndManager.injectKeyEvent( new KeyEvent( KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A ),false );

  47. Hi Radu, Thank you so much for providing this library. Injecting events through method 3 was an interesting one and i had implemented it and its working good. I am looking ahead to send touch events.
    1) I modified permissions for /dev/input/mice.
    2) And defined m_fd with /dev/input/mice attribue in Nativeinput.java file.
    3) And added ioctl(fd_kb,UI_SET_EVBIT,EV_ABS);
    ioctl(fd_kb,UI_SET_ABSBIT,ABS_X);
    ioctl(fd_kb,UI_SET_ABSBIT,ABS_Y); statements in input.c file
    4) And finally redefined event as event[2] (for x and y axis).
    Unfortunately this changes were not reflected in my app.Click event was not generated. Could you guess where i would have gone wrong. Or could suggest some reference or article regarding this task. Thanks in advance

  48. Has anyone gotten method 3 to work in Lollipop? You can’t seem to get a list of event files under /dev/input from within an app anymore, much less open an event interface, even on a rooted device with 777 permissions on /dev/, /dev/input/, and /dev/input/event* .

  49. @Radu Motisan, thanks for looking into it. From my own examination of this issue, it’s seems that it’s the app itself that’s being blocked from that path. The adb shell user can `cat` those event handles, and the app’s executing user (as listed by `ps`) can `ls /dev/input` under the default permissions through adb. They both have full access under 777 permissions. However, neither in-app Java File objects nor C open() calls (through JNI) can open those event handles under any file permissions.

    Other people have asked about this issue elsewhere too to no avail: http://stackoverflow.com/questions/27496968/inject-touch-screen-events-android-5-0-dev-input-eventx and http://www.reddit.com/r/androiddev/comments/2tr2xx/how_to_access_devinputeventx_in_lollipop/

  50. Just an update on this not working on Android 5.0. The root cause is the full SELinux enforcement introduced in Lollipop. If you set SELinux to permissive (“setenforce Permissive” as root), your apps will be able to see /dev/input/eventX again. I’m looking for a way to do this in a more target manner.

  51. @JD You can either call “setenforce Permissive” from a root shell or pass that command from your app with a Runtime exec() “su -c setenforce Permissive.”

  52. Here’s a better way to access /dev/input/ than setting SELinux to permissive on Lollipop. If you have SuperSU installed, use supolicy to modify the existing policy: supolicy –live ‘allow appdomain input_device dir { ioctl read getattr search open }’ ‘allow appdomain input_device chr_file { ioctl read write getattr lock append open }’

    Note that these changes are reverted when you restart the device.

  53. Hi,
    Could you please provide code snippet for sending key event to outside Apps (using Instrumentation)?
    Thanks in advance.

  54. Hi All,
    Could you please give the example of code snippet how to inject keys to outside Apps?

    Thanks in advance!

  55. @IOR Mate, did you find a workaround for Marshmallow as patching Supolicy doesn’t seem to be working for me.

  56. getting error while running the sample code “No implementation found for int net.pocketmagic.keyinjector.NativeInput.intEnableDebug(int) (tried Java_net_pocketmagic_keyinjector_NativeInput_intEnableDebug and Java_net_pocketmagic_keyinjector_NativeInput_intEnableDebug__I)”.
    Android version-5.0. please tell what should i do.

  57. @Radu getting error while running your sample code No implementation found for int net.pocketmagic.keyinjector.NativeInput.intEnableDebug(int) (tried Java_net_pocketmagic_keyinjector_NativeInput_intEnableDebug and Java_net_pocketmagic_keyinjector_NativeInput_intEnableDebug__I)

    Android version-5.0
    please tell what to do

  58. Hi Radu,
    Everything is working fine. I’m able to open device successfully but when i press back key, app exits. And hence i’m not able to select device from spinner after opening device. Again when i open app spinner does not populate with opened devices. Please help asap.

    Thanks for anticipation.
    Android Version: 4.2.2 (API 17)
    Device: Samsung Galaxy S4

  59. Edit:
    Problem is when i press “scan input devs”, list view populates with input devices but other layout buttons like key, tch are no where at the bottom of list view.

  60. Hi Radu,
    This is excellent article useful for our project. This seems lifesaver.But some how I guess the library not loading in my Android 4.4.2 device. The app gets crashed as soon as launched.
    Giving below logcat. Tried a lot though 🙁
    D/dalvikvm ( 9056): Trying to load lib /data/app-lib/net.pocketmagic.keyinjector-1/libinput.so 0x41fd8760
    D/dalvikvm ( 9056): Added shared lib /data/app-lib/net.pocketmagic.keyinjector-1/libinput.so 0x41fd8760
    D/dalvikvm ( 9056): No JNI_OnLoad found in /data/app-lib/net.pocketmagic.keyinjector-1/libinput.so 0x41fd8760, skipping init
    W/dalvikvm( 9056): No implementation found for native Lnet/pocketmagic/keyinjector/NativeInput; .intEnableDebug:(I)I
    D/AndroidRuntime( 9056): Shutting down VM
    W/dalvikvm( 9056): threadid=1: thread exiting with uncaught exception (group=0x41bedba8)
    E/AndroidRuntime( 9056): FATAL EXCEPTION: main
    E/AndroidRuntime( 9056): Process: net.pocketmagic.keyinjector, PID: 9056
    E/AndroidRuntime( 9056): java.lang.UnsatisfiedLinkError: Native method no found: net.pocketmagic.keyinjector.NativeInput.intEnableDebug:(I)I

    Hope to get your help. Many thanks.

  61. Edit: The target platform has been set to API-19 for my Android 4.4.2 device.
    Manifesto has been changed accordingly.
    Also tried editing the input.c file with Affixing “JNIEXPORT jxxx JNICALL”. The gcc bulid libraries have been set to proper NDK path (NDK version r11c). It seems than in all cases, the C code gets compiled properly without giving warning or error.

    (11:04:12 **** Build of configuration Default for project AndroidKeyInjector ****
    “D:\\adt-bundle-windows-x86-20140702\\adt-bundle-windows-x86-20140702\\android-ndk-r11c\\ndk-build.cmd” all
    [armeabi] Compile thumb : input libs/armeabi/libinput.so)

    But I observed that the libinput.so file generated in libs folder has size of 14K but libinput.so generated in obj folder has size of 64K.

    I am not sure where exactly it is going wrong.
    If below statement commented out, the app does not crash. So I guess either something wrong with the library generated or getting it loaded.
    m_fd = intCreate(“/dev/input/event3”, 1, 0);

    Hope to get your help. Many thanks

  62. EDIT: missed to complete console message:
    “D:\\adt-bundle-windows-x86-20140702\\adt-bundle-windows-x86-20140702\\android-ndk-r11c\\ndk-build.cmd” all
    [armeabi] Compile thumb : input libs/armeabi/libinput.so

  63. Above all three comments of mine in relevance with “AndroidKeyInjector” source from Radu. Some how it did not work but I tried more expressive and elaborate project from Radu in part 2 of this article.: http://www.pocketmagic.net/programmatically-injecting-events-on-android-part-2/
    The source code of “AndroidEventInjector” works perfectly on 4.4.2. It helped me clear many doubts and issues. Thanks Radu and all contributors for such a lovely project.

Leave a Reply