How to simulate touch from background service with sendevent or other way?

I can't execute the "sendevent" command, but found another way for myself, hope it will be helpfull for somebody.

For simulate touch I used sendPointerSync() from android.app.Instrumentation, that work only with "android.permission.INJECT_EVENTS" permission. For use it you should compile your app as a system app. To do it you should follow next steps:

  1. Getting files from android source:

    root-of-android-source-tree/out/host//framework/signapk.jar

    root-of-android-source-tree/build/target/product/security/platform.x509.pem

    root-of-android-source-tree/build/target/product/security/platform.pk8

  2. sign your app using getting files:

    Command "java -jar signapk.jar platform.x509.pem platform.pk8 YourApp-unsigned.apk" YourApp-signed.apk.

  3. adb install YourApp-signed.apk
    • Run your app
    • Use "adb shell ps" to confirm that your app is running as system.

Code with touch simulating(new thread is necessary for simulation):

Thread thread = new Thread(){
       @Override
       public void run(){
               Instrumentation m_Instrumentation = new Instrumentation();

               m_Instrumentation.sendPointerSync(MotionEvent.obtain(
                       SystemClock.uptimeMillis(),
                       SystemClock.uptimeMillis(),
                       MotionEvent.ACTION_DOWN,posx, posy, 0));
               m_Instrumentation.sendPointerSync(MotionEvent.obtain(
                       SystemClock.uptimeMillis(),
                       SystemClock.uptimeMillis(),
                       MotionEvent.ACTION_UP,width*4/5,height, 0));
       }
   };

Manifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yourapp"
    **android:sharedUserId="android.uid.system"**
    android:versionCode="1"
    android:versionName="1.0" >

Using resources:

  • Programmatically Injecting Events on Android – Part 1
  • How to compile Android Application with system permissions
  • Instruction for compile here

You can use the "swipe" input. Looking at the Input.java source code you can see the needed parameters to make a swipe.

Here is a gist I made for simulating a swipe for playing the smove game with clicks instead of swipes just to test this. You need super user access to use this implementation though.


I was about to implement your solution when I found an easier one - posting in the hope it will be helpful to someone. Since you already have a rooted device, you don't need to sign as a system app.

To simulate a touch at position (100,200), all you need to is call input from within the service using Runtime.exec as follows:

Process process = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
String cmd = "/system/bin/input tap 100 200\n";
os.writeBytes(cmd);
os.writeBytes("exit\n");
os.flush();
os.close();
process.waitFor();