I posted this in its own topic before I found this post and read it
thouroughly.
I am still having problems with Multi-touch not working as documented
on the droid.
Please read the post below for detail:

I wanted to experiment with multi-touch, so I decided to
add the controls for LunarLander to the touchscreen.

Instead of adding buttons, I defined regions on the screen that when
touched, would act like the buttons on the keyboard (for example, the
gas fires as long as you press the screen in the area defined for the
gas button, and stops firing when you release.)

To do this, I added the onTouchEvent override to the LunarView class
as follows:

   /**
     * Standard override to get Touch Screen Events.
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return thread.doTouchScreen(event);
    }

Then, I added a function to the LunarThread called doTouchScreen.  I
also added variables to define the boundaries of the touch areas on
the screen for the "buttons" The boundaries are defined as follows and
placed in the variable declaration location of the LunarThread:

        //* Y boundary of left and right turn button **/
        private float TurnButton_Y;

        //* X Boundary of the fire Button (left side of button)
        private float fireButton_X;

        //* X boundary of left turn button **/
        private float leftTurnButton_X = 100;

        //* X boundary of right turn button **/
        private float rightTurnButton_X = 200;

The doTouchScreen code is the following:

 boolean doTouchScreen(MotionEvent event) {

                boolean handled = true;

                synchronized (mSurfaceHolder) {

                  int numevents = event.getPointerCount();
                  int action = event.getAction();
                  int ptrId = event.getPointerId(0);

              if(numevents > 1)
                 ptrId = (action & MotionEvent.ACTION_POINTER_ID_MASK)


MotionEvent.ACTION_POINTER_ID_SHIFT;
                 action = action & MotionEvent.ACTION_MASK;

              int ptrIndex = event.findPointerIndex(ptrId);

              float X = event.getX(ptrIndex);
              float Y = event.getY(ptrIndex);

                if(action == event.ACTION_DOWN || action ==
event.ACTION_MOVE)
                {
                        if(Y > TurnButton_Y)
                                {
                                        if(X < leftTurnButton_X)
                                        {
                                                mRotating = -1;
                                                turnButtonID = ptrId;
                                        }
                                        else if (X <
rightTurnButton_X)
                                        {
                                                mRotating = 1;
                                                turnButtonID = ptrId;
                                        }
                                        else if (X > fireButton_X)
                                        {
                                                setFiring(true);
                                                gasButtonID = ptrId;
                                        }

                                        handled =  true;
                    }
                        handled = true;
                }
                else if(action == event.ACTION_UP || action ==
event.ACTION_CANCEL)
                {

                        if(gasButtonID == ptrId)
                        {
                                setFiring(false);
                                gasButtonID = -1;
                                handled = true;
                        }
                        if(turnButtonID == ptrId)
                        {
                                mRotating = 0;
                                turnButtonID = -1;
                                handled = true;
                        }
                        handled = true;
            }

                }
                return handled;
        }

During testing I found consistent problems when performing the
following pattern:

1) Touch finger 1 down on gas button area
2) Touch finger 2 down on turn button area
3) Lift finger 1 off of gas button
4) Touch finger 1 back on to gas button

The problem is that after performing this pattern, the gas button
fails to work.  Lifting the gas button and then placing it down a
third time causes the button to work again.  This is consistent every
time I try this. Debugging yielded the following strange results:

1) Finger 1 goes down at location X, Y.
     X = X
     Y = Y
     action = ACTION_DOWN,
     ptrID = 0
     ptrIndex = 0
     numEvents = 1
2) Finger 2 goes down at location X2, Y2.
     X = X2
     Y = Y2
     action = ACTION_POINTER_DOWN
     ptrID = 1
     ptrIndex = 1
     numEvents = 2
3) Finger 1 goes up
    X = X
    Y = Y
    action = ACTION_POINTER_UP
    ptrID = 0
    ptrIndex = 0
    numEvents = 2

So far, so good...

4) Finger 1 goes back down at location X, Y
     X = X2
     Y = Y2
     action = ACTION_POINTER_DOWN
     ptrID = 0
     ptrIndex = 0
     numEvents = 2

****** Here is the first problem:   The X and Y coordinates returned
are incorrect, they are the coordinates for the other finger (finger
2).  When finger 1 was removed, finger 2's data moved to the 0 index,
but it still retained ID 1.  When finger 1 went back down, it
correctly was identified as ID 0, but instead of adding a new index
for finger 1 data, it just returns index 0, which is finger 2's
data!

5) Lift Finger 1 back up again from location X, Y
     X = X2
     Y= Y2
     action = ACTION_POINTER_UP
     ptrIndex = 1
     ptrID = 1
     numEvents = 2

*** WHATWHAT?!?  I lifted finger 1 up, which should be ID 0,  why is
ID 1 reporting that it goes up.  Also, why is it given data index 1,
which I would assume should be finger 1's data, but the coordinates
are still those of finger 2.  Yes, I have a headache too...

6) Place Finger 1 back on the screen at location X, Y.  Again...
     X = X
     Y = Y
     action = ACTION_POINTER_DOWN
     ptrIndex = 1
     ptrID = 1
     numEvents = 2

OK, now finger 1 has taken ID 1, which originally belonged to finger
2.  Keep in mind, this whole time, Finger 2 has NEVER moved.  It
should still have ID 1 if I understand correctly, only the data
indexes should change.  This behavior is not consistent with the
documentation.  And wait, it gets better....

7)  Remove Finger 1 from location X, Y for the last time
     X = X
     Y = Y
     action = ACTION_POINTER_UP
     ptrIndex = 1
     ptrID = 1
     numEvents = 2

This looks good.  But what about finger 2 which should still have ID
1, but apparently does not.

8) Remove Finger 2 from location X2, Y2
     X = X2
     Y = Y2
     action = ACTION_UP
     ptrIndex = 0
     ptrID = 0
     numEvents = 1

So, even though finger 2 went down second and was originally assigned
ID 1, it somehow magically has ID 0, and the correct data at index 0.
Any insight into what I might be doing wrong, or if I am indeed NOT
crazy
would be greatly greatly appreciated.

I know this is a long note so I pray that some of you have the
gumption to read the whole thing and give it a try yourself to see if
you can duplicate my results.  This was all debugged on a live DROID,
connected to the PC via a USB cable.

Thanks in advance to any who may help, or just console me.

-Colin

On Nov 15 2009, 8:39 pm, Dianne Hackborn <hack...@android.com> wrote:
> This is the intended behavior.  There are basically five actions you need to
> care about.  For all of them, you can mask out ACTION_MASK to just look at
> the action part.
>
> These three are all you need to care about if you aren't interesting in
> multitouch:
>
> 1. ACTION_DOWN, the existing standard action for the first press.
> 2. ACTION_MOVE, any change in state that doesn't involve a finger going up
> or down.
> 3. ACTION_UP, the existing standard action for the last release.
>
> And if you want to keep track of addition fingers going down, you want
> these:
>
> 4. ACTION_POINTER_DOWN, when an addition pointer goes down.  The pointer ID
> mask tells you the new identifier for this pointer.
> 5. ACTION_POINTER_UP, when a pointer goes up by there are still active
> pointers.  The pointer ID mask tells you the identifier for this pointer.
>
> Note that it was deliberate to keep the actions for the first and last
> pointer different from the other pointers, both for backwards compatibility
> and the fact that the majority of code doesn't care about multitouch.
>
> Now that the 2.0 source is available, here are some example uses of the API:
>
> http://android.git.kernel.org/?p=platform/development.git;a=blob;f=ap...
>
> <http://android.git.kernel.org/?p=platform/development.git;a=blob;f=ap...>http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;...
> <http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;...>
>
>
>
> On Sun, Nov 15, 2009 at 1:41 PM, davemac <davemac...@gmail.com> wrote:
> > I think I've got this figured out. Almost. With multi-touch support,
> > getAction() can return a compound value representing the pointerID in
> > the second byte and the action value in the first byte. For example,
> > if two fingers are down, and pointerID 1 is lifted (i.e., finger 2),
> > getAction() returns a value of 262 (0x100 or 256 to represent
> > pointerID 1, and 6 to represent up for a compound value of 0x106 or
> > 262). I'm curious why it was done this way instead of using 0 for down
> > and 1 for up, even when pointers are involved. Things get a little
> > weird because of the differences. Here's an example (note I'm using a
> > Motorola Droid phone here so this may behave differently on other
> > devices):
>
> > Press finger 1 to the screen (action value of 0)
> >    finger 1 gets pointerID 0, no problem, pointerID is 0, down is 0
> > Press finger 2 to the screen (action value of 261)
> >    finger 2 gets pointerID 1, a little weird, could have been 256
> > instead?
> > Lift finger 1 from the screen (action value of 6)
> >    finger 2 is still pointerID 1, action could still have been 1?
> > Lift finger 2 from the screen (action value of 1)
> >    finger 2 is still pointerID 1, but the action value is not 262 or
> > 257 it's 1
>
> > It would seem I can't use the bitmasks reliably in all cases. If I
> > always inspect the action value for the pointerID and the action
> > value, I get messed up at the end because pointerID has vanished. And
> > 0 seems to be equivalent to 5, and 1 to 6.
>
> > Is this something you'd consider a bug or is this how it's supposed to
> > work? Should we expect it to continue to work this way?
>
> > Thanks for your help.
>
> > - dave
>
> > On Oct 27, 4:28 pm, Dianne Hackborn <hack...@android.com> wrote:
> > > On Tue, Oct 27, 2009 at 2:02 PM, MrChaz <mrchazmob...@googlemail.com>
> > wrote:
>
> > > > Thanks for the info,
>
> > > > Wouldn't this
> > > > Finger 1 up: MotionEvent ACTION_POINTER_1_UP with one pointer, whose
> > > > ID is
> > > > 1.
> > > > need to be ID of 0?  Or am I mis-understanding the purpose of the UP
> > > > action?
>
> > > Good point.  Actually my example was not very good because at the places
> > > where there is an up transition, the last position of the pointer going
> > up
> > > is included in the event stream -- so in all of these, you would receive
> > > both 0 and 1.  It is in the following move event that you will only get
> > the
> > > information for the pointers that are currently down.
>
> > > --
> > > Dianne Hackborn
> > > Android framework engineer
> > > hack...@android.com
>
> > > Note: please don't send private questions to me, as I don't have time to
> > > provide private support, and so won't reply to such e-mails.  All such
> > > questions should be posted on public forums, where I and others can see
> > and
> > > answer them.
>
> > --
> > You received this message because you are subscribed to the Google
> > Groups "Android Developers" group.
> > To post to this group, send email to android-developers@googlegroups.com
> > To unsubscribe from this group, send email to
> > android-developers+unsubscr...@googlegroups.com<android-developers%2bunsubscr...@googlegroups.com>
> > For more options, visit this group at
> >http://groups.google.com/group/android-developers?hl=en
>
> --
> Dianne Hackborn
> Android framework engineer
> hack...@android.com
>
> Note: please don't send private questions to me, as I don't have time to
> provide private support, and so won't reply to such e-mails.  All such
> questions should be posted on public forums, where I and others can see and
> answer them.
-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to