How to simulate touch from background service with sendevent or other way?
Solution 1:
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:
-
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
-
sign your app using getting files:
Command "java -jar signapk.jar platform.x509.pem platform.pk8 YourApp-unsigned.apk" YourApp-signed.apk.
- 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
Solution 2:
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();