0

I'm programming for a virtual mouse cursor by Android studio and that is from an example in this website and its code. I have an overlay cursor and following code to go back to the home screen.

Intent newActivity = new Intent(Intent.ACTION_MAIN);
newActivity.addCategory(Intent.CATEGORY_HOME);
newActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(newActivity);

My problem is how can I apply the click action to my cursor when the view is outside my app (maybe home screen or other apps). I tried this

Instrumentation m_Instrumentation = new Instrumentation();
m_Instrumentation.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(),SystemClock.uptimeMillis(),MotionEvent.ACTION_DOWN,new_x, new_y, 0));
m_Instrumentation.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(),SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, new_x, new_y, 0));

but it shown

Injecting to another application requires INJECT_EVENTS permission.

Then, I added <uses-permission android:name="android.permission.INJECT_EVENTS"/> in AndroidManifest.xml. There is an error called "Permission is only granted to system apps" so that I can't use it in my app to execute virtual click. If I just close the inspection system, it still doesn't work to my app.

After that, I tried dispatchTouchEvent with Handler but it only works in myself app (Can't be used in the home screen to open other apps.)

dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis() + 100, MotionEvent.ACTION_DOWN, new_x, new_y, 0));
dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis() + 100, MotionEvent.ACTION_UP, new_x, new_y, 0));

Thanks for your replying.
My simulated mobile device is Android 4.4.2.
Compile Sdk version: Android 6.0
Build tool version: 24.0.3

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Jarvus
  • 11
  • 2

2 Answers2

0

You can't. You're not allowed to for security reasons- they don't want one app being able to send commands to another for security purposes. THe instrumentation stuff is for unit tests, it works only because the test suite is part of the same application.

Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127
  • Thanks. If I root my phone, how can I open the permission of INJECT_EVENTS in my project? – Jarvus Feb 27 '17 at 06:06
  • You'd need to add the permission to your manifest, then install yourself in the system apps directory (depending on your version, either /system/apps, or /system/priv-apps). Any app installed there can request system permissions. So it won't work in a play store app, but it will be ok for a personal app. – Gabe Sechan Feb 27 '17 at 06:07
  • I installed [this](https://kingroot.net/#) to root my system, then added INJECT_EVENTS permission to my AndroidManifest. However, it shown the same **Injecting to another application requires INJECT_EVENTS permission** in my debug window. – Jarvus Feb 27 '17 at 06:20
  • Did you install the app to the proper systems apps directory? See http://www.androidauthority.com/install-user-app-as-system-app-how-to-93522/ – Gabe Sechan Feb 27 '17 at 06:22
  • I followed steps in the web, cut my app to system/app and then changed its permissions. In the moment, my owner and group is **root**. After reopening my phone and installed the app. It's error and crash again. – Jarvus Feb 27 '17 at 15:06
  • Should I create a system certificate? like [this](http://stackoverflow.com/questions/5383401/android-inject-events-permission/7328055) but I can't find platform.pk8 and platform.x509.pem when I used Android studio and keytool-importkeypair. – Jarvus Feb 27 '17 at 16:29
  • @jarvuschen Did you ever figure out how to do this? I'm trying the same thing and getting the same exact errors – Elliptica Aug 24 '17 at 22:08
0

you might find this link helpful :)

https://github.com/chetbox/android-mouse-cursor

it's without rooting and he managed to send clicks using those lines

    private void click() {
    Log.d(TAG, String.format("Click [%d, %d]", cursorLayout.x, cursorLayout.y));
    AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
    if (nodeInfo == null) return;
    AccessibilityNodeInfo nearestNodeToMouse = findSmallestNodeAtPoint(nodeInfo, cursorLayout.x, cursorLayout.y + 50);
    if (nearestNodeToMouse != null) {
        logNodeHierachy(nearestNodeToMouse, 0);
        nearestNodeToMouse.performAction(AccessibilityNodeInfo.ACTION_CLICK);
    }
    nodeInfo.recycle();
}