Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

onTouchEvent by code via Instrumentation

I want to accomplish following:

I have two buttons. When first button is pressed,
it will fire onTouchEvent on second button, thus pressing second button.

Here is the excerpt of code that fires event:

int test1[] = new int[2];
button2.getLocationInWindow(test1);   //--->getting coordinates of second button
Instrumentation m_Instrumentation = new Instrumentation();
//firing event
m_Instrumentation.sendPointerSync(MotionEvent.obtain(android.os.SystemClock.uptimeMillis(),android.os.SystemClock.uptimeMillis(),MotionEvent.ACTION_DOWN,test1[0]+10, test1[1]+10, 0));

Note: I use genymotion emulator.

Error log:

07-08 12:47:38.743: E/InputEventReceiver(6849): Exception dispatching input event.
07-08 12:47:38.743: E/MessageQueue-JNI(6849): Exception in MessageQueue callback: handleReceiveCallback
07-08 12:47:38.743: E/MessageQueue-JNI(6849): java.lang.RuntimeException: This method can not be called from the main application thread
07-08 12:47:38.743: E/MessageQueue-JNI(6849):   at android.app.Instrumentation.validateNotAppThread(Instrumentation.java:1651)
07-08 12:47:38.743: E/MessageQueue-JNI(6849):   at android.app.Instrumentation.sendPointerSync(Instrumentation.java:933)
07-08 12:47:38.743: E/MessageQueue-JNI(6849):   at com.example.touchtest1.MainActivity.fireEvent(MainActivity.java:55)
07-08 12:47:38.743: E/MessageQueue-JNI(6849):   at com.example.touchtest1.MainActivity$MyTouchListener.onTouch(MainActivity.java:75)
07-08 12:47:38.743: E/MessageQueue-JNI(6849):   at android.view.View.dispatchTouchEvent(View.java:7701)
07-08 12:47:38.743: E/MessageQueue-JNI(6849):   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
07-08 12:47:38.743: E/MessageQueue-JNI(6849):   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
07-08 12:47:38.743: E/MessageQueue-JNI(6849):   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
07-08 12:47:38.743: E/MessageQueue-JNI(6849):   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
07-08 12:47:38.743: E/MessageQueue-JNI(6849):   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
07-08 12:47:38.743: E/MessageQueue-JNI(6849):   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
07-08 12:47:38.743: E/MessageQueue-JNI(6849):   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
07-08 12:47:38.743: E/MessageQueue-JNI(6849):   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
07-08 12:47:38.743: E/MessageQueue-JNI(6849):   at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2068)
07-08 12:47:38.743: E/MessageQueue-JNI(6849):   at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1515)
07-08 12:47:38.743: E/MessageQueue-JNI(6849):   at android.app.Activity.dispatchTouchEvent(Activity.java:2458)
07-08 12:47:38.743: E/MessageQueue-JNI(6849):   at android.support.v7.app.ActionBarActivityDelegateICS$WindowCallbackWrapper.dispatchTouchEvent(ActionBarActivityDelegateICS.java:260)
07-08 12:47:38.743: E/MessageQueue-JNI(6849):   at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2016)
07-08 12:47:38.743: E/MessageQueue-JNI(6849):   at android.view.View.dispatchPointerEvent(View.java:7886)
07-08 12:47:38.743: E/MessageQueue-JNI(6849):   at  android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:3954)
07-08 12:47:38.743: E/MessageQueue-JNI(6849):   at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3833)

However, it is not going as intended. Where can be problem?

With regards

like image 780
nurgasemetey Avatar asked Jul 08 '14 12:07

nurgasemetey


1 Answers

Based on the error and the excerpt at the bottom of this documentation, it looks like you can't run this on the main thread (in other words, the UI thread).

A possible solution would be to run it in another thread. It would look like this:

int test1[] = new int[2];
button2.getLocationInWindow(test1);   //--->getting coordinates of second button
final Instrumentation m_Instrumentation = new Instrumentation();
//firing event

new Thread(new Runnable() {
    @Override
    public void run() {
        m_Instrumentation.sendPointerSync(MotionEvent.obtain(
               android.os.SystemClock.uptimeMillis(),
               android.os.SystemClock.uptimeMillis(),
               MotionEvent.ACTION_DOWN,test1[0]+10, test1[1]+10, 0));
    }
}).start();

Note that I changed your m_Instrumentation to a final variable so that it could be used in a different thread.

like image 171
Andrew Schuster Avatar answered Oct 06 '22 05:10

Andrew Schuster