Android Key Injection

 In android, you can able to remap the given input at the running time. For example, you can remap the volume up button to volume down action all over your android device. This we can able to do in the application layer if we have an Inject_Event_Permission.

     Inject_event_permission helps application developers to Remap and Inject the keys to any other applications. But for injecting the key events using Inject_event_permission requires the Accessibility service.

    Since the Accessibility service works at the layer of the android framework. It can be able to capture the key events before it reaches the application layer. Also, we require the Instrumentation.java class to remap the keys.

   Instrumentation is internally working with Android Input manager and also it can remap the keys. But it requires some of the key parameters for remapping the keys.


 Questions :

 1 . What is the purpose of Inject_Event_Permission?
   
         In android, we can control another application key inputs from our application. I.e assume that you have the volume up button should act as volume down all over the device ( In every place in your phone ) . In this case we can use the Key_Inject_Event_Permission.

2. Is Inject_Event_Permission like normal Application permission?

       No, Inject_Event_Permission is something special. Using that we could able to track the other application, So Android OS has certain constraints for this permission. The Application developer should have either ROOT permission or Device signature. So you can't simply give this application to the Manifest.xml file.

Methods :

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.


// key down
m_WndManager.injectKeyEvent( new KeyEvent( KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A ),true );
// key up
m_WndManager.injectKeyEvent( new KeyEvent( KeyEvent.ACTION_UP, KeyEvent.KEYCODE_A ),true );
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:


// key down
m_WndManager.injectKeyEvent( new KeyEvent( KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A ),true );
// key up
m_WndManager.injectKeyEvent( new KeyEvent( KeyEvent.ACTION_UP, KeyEvent.KEYCODE_A ),true );

To send touch/mouse events use:

//pozx goes from 0 to SCREEN WIDTH , pozy goes from 0 to SCREEN HEIGHT
m_WndManager.injectPointerEvent(MotionEvent.obtain(SystemClock.uptimeMillis(),
SystemClock.uptimeMillis(),MotionEvent.ACTION_DOWN,pozx, pozy, 0), true);
m_WndManager.injectPointerEvent(MotionEvent.obtain(SystemClock.uptimeMillis(),
SystemClock.uptimeMillis(),MotionEvent.ACTION_UP,pozx, pozy, 0), true);


Method 2: Using an instrumentation object
This is a clean solution based on public API, but unfortunately, it still requires that INJECT_EVENTS' permission.


Instrumentation m_Instrumentation = new Instrumentation();
m_Instrumentation.sendKeyDownUpSync( KeyEvent.KEYCODE_B );
For touch events

Instrumentation m_Instrumentation = new Instrumentation();
m_Instrumentation.sendKeyDownUpSync( KeyEvent.KEYCODE_B );
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 the method
1). So this is the same thing, but packed nicely in an easy to use API:

public void  sendPointerSync(MotionEvent event) {
          validateNotAppThread();
          try {
              (IWindowManager.Stub.asInterface(ServiceManager.getService("window")))
                  .injectPointerEvent(event, true);
          } catch (RemoteException e) {
          }
     }

Reference Link:  https://www.pocketmagic.net/injecting-events-programatically-on-android/

Comments