Syeda Zunaira
Syeda Zunaira

Reputation: 5207

Trigger ACTION_POINTER_DOWN event programmatically

want to trigger on two fingers down event for a few milliseconds.

I am able to trigger simple touch event by using this code:

 objImageView.getLocationOnScreen(coords);
                    int xa = coords[0];
                    int ys = coords[1];
                    objImageView.dispatchTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, xa, ys, 0.5f, 5, 0, 1, 1, 0, 0));
                    objImageView.dispatchTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, xa, ys, 0.5f, 5, 0, 1, 1, 0, 0));
                    objImageView.dispatchTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, xa, ys, 0.5f, 5, 0, 1, 1, 0, 0));

Now if I try to do the same for ACTION_POINTER_DOWN nothing is happening. Here is my code:

  int[] coords = new int[2];
        parentLayout.getLocationOnScreen(coords);
        int xa = coords[0];
        int ys = coords[1];
        parentLayout.dispatchTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_POINTER_DOWN, xa, ys, 0.5f, 5, 0, 1, 1, 0, 0));
        parentLayout.dispatchTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, xa, ys, 0.5f, 5, 0, 1, 1, 0, 0));
        parentLayout.dispatchTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_POINTER_UP, xa, ys, 0.5f, 5, 0, 1, 1, 0, 0));

I want to trigger the same event which called when user places the two fingers down and hold fingers there for a few milliseconds.

Upvotes: 0

Views: 1092

Answers (4)

TomUser
TomUser

Reputation: 31

This is an old thread, but since, none of the answers were complete, adding a bit more info here for future folks. Like the author I wanted simulate two touches, and even though my sequence wa:

ACTION_DOWN(0), PointerCount = 1
ACTION_POINTER_DOWN(5), PointerCount = 2
ACTION_POINTER_UP(6), PointerCount = 2
ACTION_UP(1), PointerCount = 1

It was simply not working, I only then understood, that you need to shift action by pointer count.

if ((action == ACTION_POINTER_DOWN || action == ACTION_POINTER_UP) && pointerCount > 1)
   action |= 256 << (pointerCount - 2);

In other words, the action values become

ACTION_DOWN(0), PointerCount = 1
ACTION_POINTER_DOWN(261), PointerCount = 2
ACTION_POINTER_UP(262), PointerCount = 2
ACTION_UP(1), PointerCount = 1

Only then it started working for me

Upvotes: 0

Eyal Biran
Eyal Biran

Reputation: 5746

To simulate "two fingers" you will need to create a motion event that includes more than one pointer, as you do now.

To do that, use the MotionEvent obtain variation that supports multiple pointers as is documented here.

MotionEvent obtain (long downTime, 
                long eventTime, 
                int action, 
                int pointerCount, 
                PointerProperties[] pointerProperties, 
                PointerCoords[] pointerCoords, 
                int metaState, 
                int buttonState, 
                float xPrecision, 
                float yPrecision, 
                int deviceId, 
                int edgeFlags, 
                int source, 
                int flags)

First you should dispatch an event for the first finger (exactly like you did) and when you are about to simulate MotionEvent.ACTION_POINTER_DOWNyou should use the above obtain variation.

Fields are pretty self explanatory, make sure the params are:

  1. pointerCount = 2
  2. pointerProperties = [firstFingerPointerProperties, secondFingerPointerProperties]
  3. pointerCoords = [firstFingerPointerCoords, secondFingerPointerCoords]

Upvotes: 1

user1643723
user1643723

Reputation: 4192

You should generate a sequence like this: ACTION_DOWN -> ACTION_POINTER_DOWN -> optionally small delay -> ACTION_POINTER_UP -> ACTION_UP.

You should also set pointer index (and other metadata) correctly for second pointer, because otherwise the gesture detection code may be unable to tell that ACTION_POINTER_DOWN for secondary press is describing a secondary finger, not primary.

Use this method to fill in all necessary information for ACTION_POINTER_DOWN describing second press. Make sure to pass correct pointerProperties!

Upvotes: 1

Andrii Omelchenko
Andrii Omelchenko

Reputation: 13343

Documentation said that: "A gesture starts with a motion event with ACTION_DOWN that provides the location of the first pointer down. As each additional pointer that goes down or up, the framework will generate a motion event with ACTION_POINTER_DOWN or ACTION_POINTER_UP accordingly." so You need trigger simple touch event at first. And take a look at this question.

Upvotes: 1

Related Questions