Aaaaar, I didn't see Dianne's response (nor Niko's) when I posted my last response, because I didn't realize that there was a "page 2".
Thanks, Dianne, for your explanation and for posting the examples! -- PJ On Nov 16, 1:57 am, PJ <pjbar...@gmail.com> wrote: > I think I've figured it out for you, Dave. :) Bear with me. > > Let's look at the constants in MotionEvent: > > ACTION_MASK = 0x000000ff > ACTION_POINTER_ID_MASK = 0x0000ff00 > ACTION_POINTER_ID_SHIFT = 8 > > This confirms that the lowest order byte represents the action and the > next byte represents the pointer ID. > > Now, the inconsistency that you observed (0 vs. 5, 1 vs. 6) can be > explained by the fact that the action values for the primary pointer > are different from the action values for non-primary pointers: > > For primary pointers: > ACTION_DOWN = 0 > ACTION_UP = 1 > > For non-primary pointers: > ACTION_POINTER_DOWN = 5 > ACTION_POINTER_UP = 6 > > So, hopefully that explains why you experienced those > "inconsistencies". > > Now, notice that there are some "convenience constants" that we can > use to prevent doing all of this dirty work ourselves. Let's see if > they jive: > > ACTION_POINTER_2_DOWN = 261 = 0x0100 | 0x0005 > ACTION_POINTER_2_UP = 262 = 0x0100 | 0x0006 > ACTION_POINTER_3_DOWN = 517 = 0x0200 | 0x0005 > ACTION_POINTER_3_UP = 518 = 0x0200 | 0x0006 > > Important: Notice that the numbers "2" and "3" in the constant names > are 1-based and not 0-based. However, PointerID's 0-based. So, for > example, "POINTER_2" means PointerID = 0x01. > > So, "POINTER_1" should mean PointerID = 0x00. And note that the > documentation says "Pointer IDs start at 0, with 0 being the primary > (first) pointer in the motion." > > Now, let's look at the following values: > ACTION_POINTER_1_DOWN = 5 > ACTION_POINTER_1_UP = 6 > > POINTER_1 represents PointerID=0. So, here we might have an apparent > contradiction in documentation. Why would PointerID=0, a primary > pointer, generate non-primary actions? > > However, one possibility is that PointerID=0 ceases to become a > "primary pointer" when 2+ fingers are touching the device. I don't > see that documented anywhere, but that's the only explanation I can > think of for your Motorola Droid's behavior. > > Based on the scenario you described above, my best guess is that your > Droid is following these interpretations/rules: > * If there is only one finger touching the device, it is treated as > PointerID=0 and as a primary, and so only ACTION_DOWN (0) and > ACTION_UP (1) events are generated. > * If there are 2+ fingers touching the device, then the first finger > is still treated as PointerID=0, but NOT as a "primary" (e.g. it > generates ACTION_POINTER_UP=6, not ACTION_UP=1). > * Whenever there are 2 fingers touching the device and one finger is > lifted, the sole remaining finger becomes PointerID=0 and "primary", > even if it was originally a "2nd" or higher finger. > > If you apply these rules, it would explain your Droid's behavior: > > > Press finger 1 to the screen (action value of 0) > > Correct: 0x0000 | 0x0000 (finger 1 is a primary) > > > Press finger 2 to the screen (action value of 261) > > Correct: 0x0100 | 0x0005 (neither finger is a primary) > > > Lift finger 1 from the screen (action value of 6) > > Correct: 0x0000 | 0x0006 (finger 1 is no longer a primary; finger 2 is > the only finger so it becomes PointerID=0 and primary) > > > Lift finger 2 from the screen (action value of 1) > > Correct: 0x0000 | 0x0001 (finger 2 is primary) > > So, that should explain your Droid's behavior. > > Now, I'm not saying that those extra interpretations/rules are correct > and will/should be adopted by all devices. But I think it's a decent > interpretation. I'm not terribly surprised that your Droid is acting > like that. > > What do you think? > -- PJ > > On Nov 15, 3: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 For more options, visit this group at http://groups.google.com/group/android-developers?hl=en