Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android multitouch and getActionMasked()

I have a some small questions to do with the masking of touch events. I have read many things on here and elsewhere but am still a little confused with parts.

1) Is event.getActionMasked() same as event.getAction() & MotionEvent.ACTION_MASK (they appear to be on Samsung S2 and HTC Desire)

2) Will the two above commands give all the information and more than that event.getAction() alone will, or is it different.

3) I have written a peice of code which simple says where is being touch and with which pointerId, or if the pointer is not in use (only written for two touches at the moment). It seems to work correctly on the devices mention above, however I know how some devices can act very differently if not done absolutely correct. I am therefore wondering if the following is correct and will behave on all devices.

boolean pointer0down=false, pointer1down=false;
String st="", str0 ="", str1 ="";

public boolean onTouchEvent( MotionEvent event )
{

  if (event.getActionMasked()==MotionEvent.ACTION_UP
        ||event.getActionMasked()==MotionEvent.ACTION_POINTER_UP
        ||event.getActionMasked()==MotionEvent.ACTION_CANCEL)
   {
     if (event.getPointerId((event.getActionIndex()& MotionEvent.ACTION_MASK))==0)
        pointer0down=false;
     if (event.getPointerId((event.getActionIndex()& MotionEvent.ACTION_MASK))==1)
        pointer1down=false;
   }

  if (event.getActionMasked()==MotionEvent.ACTION_DOWN
    ||event.getActionMasked()==MotionEvent.ACTION_POINTER_DOWN)
  {
    if (event.getPointerId((event.getActionIndex()& MotionEvent.ACTION_MASK))==0)
       pointer0down=true;
    if (event.getPointerId((event.getActionIndex()& MotionEvent.ACTION_MASK))==1)
       pointer1down=true;
   }

 if (pointer0down)
    str0="\tx: " + event.getX(0) + "\ty: "+event.getY(0);
 else
    str0="\tNot down";

 if (pointer1down )
    str1="\tx: " + event.getX(1) + "\ty: "+event.getY(1);
 else
    str1="\tNot down";

 st="pointer0:"+str0+"\npointer1:"+str1;

    return true;
} 
like image 571
user1529408 Avatar asked Dec 04 '12 20:12

user1529408


1 Answers

Some background -

The integer returned from getAction is a packed integer that encodes both the action code (e.g ACTION_DOWN) and pointer index (e.g which finger).

For single touch, since there is only one finger involved there is no need to store the pointer index so the value is just the action code. Hence its safe to do something like getAction() == ACTION_DOWN

For multi touch, this comparison is incorrect b/c you have the extra pointer index in the packaged integer. You can extract the action code by doing getAction() & ACTION_MASK and extract the pointer index by doing getAction() & ACTION_POINTER_INDEX_MASK

Now to your question -

1: Yes. think of getActionMasked as a helper method that extract the action code bits. To extract the pointer index you have the equivalent getActionIndex helper method. Both these methods will work for single or multi touch hence they are the "safest".

2: As explained above, getAction also encodes pointer index for multitouch

3: there is a bug in your code. event.getPointerId((event.getActionIndex() & MotionEvent.ACTION_MASK)) is technically incorrect. Instead you should be doing event.getPointerId(event.getActionIndex()). You are getting very lucky with the incorrect logical and operator on getActionIndex which turns out to be 2 bytes and the mask is itself 2 bytes (0xff) :)

like image 93
numan salati Avatar answered Oct 26 '22 23:10

numan salati