Why doesn't this MotionEvent simulation work?
Asked Answered
D

2

6

In one of the views in an exercise app, am trying to perform text selection programmatically.

I am able to (programmatically) enter "text selection mode", which is visually indicated by CursorControllers (AKA handles) on the top-left corner of the view.

If I manually drag the right CursorController, then click it again (in the emulator), it works as expected (perfectly), showing a brief message: "Text copied to clipboard".

But when I try to programmatically drag that right CursorController, nothing happens.

The way I try to do this is by simulating a MotionEvent. In the view, I call:

  event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, x, y, 0);
  MainActivity.onTouch(this, event);

In the MainActivity I of course implement OnTouchListener:

@Override
public boolean onTouch(View v, MotionEvent event) { // called BEFORE button's onTouchEvent()
    Log.v("MainActivity::onTouch()", describeEvent(v, event));
    switch (event.getAction()) { 
        case MotionEvent.ACTION_DOWN: 
        case MotionEvent.ACTION_UP: 
            if (!v.hasFocus()) { 
                v.requestFocus(); 
             } 
             break; 
    } 
    return false; 
}

If I understand correctly, by mere returning 'false' from onTouch, Android keeps looking for another UI object to consume the MotionEvent object, eventually reaching my view.

Why doesn't this happen?

I must be missing something very fundamental...

Denotative answered 9/3, 2011 at 18:17 Comment(0)
D
1

For lack of a working solution, I can only conclude that what I have been trying to accomplish isn't possible on the Android, for reasons of security. An explanation can be found in the following link: How to send synthesized MotionEvent through the system?

Denotative answered 22/3, 2011 at 16:29 Comment(0)
O
0

The OnTouchListener is called inside the View from dispatchTouchEvent which in turn has been called from ViewGroup or a TouchDelegate. If you call the listener from your view it simply does what ever you have there and then returns. It doesn't magically delegate the touch event anywhere.

Instead Call dispatchTouchEvent() on your view to get the correct result.

For unit testing your application behavior on text selection etc. See http://developer.android.com/resources/tutorials/testing/activity_test.html

Orson answered 12/3, 2011 at 20:32 Comment(1)
Kudos for being the 1st to try answering this difficult question. Unfortunately however, dispatchTouchEvent() doesn't produce the much yearned for events. Perhaps @DJC was right in his answer to the following question: #5240787Denotative

© 2022 - 2024 — McMap. All rights reserved.