chriz
chriz

Reputation: 245

MotionEvent multiple touch events get mixed up and influence each other (see demo video)

Purpose of the app:

A simple app that draws a circle for every touch recognised on the screen and follows the touch events. On a 'high pressure reading' getPressure (int pointerIndex) the colour of the circle will change and the radius will increase. Additionally the touch ID with getPointerId (int pointerIndex), x- and y-coordinates and pressure are shown next to the finger touch.

Following a code snipplet of the important part (please forgive me it is not the nicest code ;) I know)

protected void onDraw(Canvas canvas){

    //draw circle only when finger(s) is on screen and moves 
    if(iTouchAction == (MotionEvent.ACTION_MOVE)){
        int x,y;
        float pressure;

        //Draw circle for every touch
        for (int i = 0; i < touchEvent.getPointerCount(); i++){
            x = (int)touchEvent.getX(i);
            y = (int)touchEvent.getY(i);
            pressure = touchEvent.getPressure(i);

            //High pressure
            if (pressure > 0.25){
                canvas.drawCircle(x, y, z+30, pressureColor);
                canvas.drawText(""+touchEvent.getPointerId(i)+"  | "+x+"/"+y, x+90, y-80, touchColor);
                canvas.drawText(""+pressure, x+90, y-55, pressureColor);
            }else{ //normal touch event 
                canvas.drawCircle(x, y, z, touchColor);
                canvas.drawText(""+touchEvent.getPointerId(i)+" | "+x+"/"+y, x+60, y-50, touchColor);
                canvas.drawText(""+pressure, x+60, y-25, pressureColor);
            }
        }           
    }
}

The problem:

A HTC Desire running Android 2.1 is the test platform. The app works fine and tracks two finger without a problem. But it seems that the two touch points interfere with each other when they get t0o close -- it looks like they circles 'snap'to a shared x and y axle. Sometimes they even swap the input coordinates of the other touch event. Another problem is that even though getPressure (int pointerIndex) refers to an PointerID both touch event have the same pressure reading.

As this is all a bit abstract, find a video here: http://www.youtube.com/watch?v=bFxjFexrclU

My question:

  1. Is my code just simply wrong?
  2. Does Android 2.1 not handle the touch events well enough get things mixed up?
  3. Is this a hardware problem and has nothing to do with 1) and 2)?

Thank you for answers and/or relinks to other thread (sorry could find one that address this problem).

Chris

Upvotes: 3

Views: 4178

Answers (2)

Philzen
Philzen

Reputation: 4647

Anyone tried this fix for multitouch gestures on older androids before? I am planning to evaluate it for my own project, as it also deals with android 1.x/2.x buggy multitouch.

Luke seems to have covered the problem described here as well as other common touch input problems on pre-3.x devices.

Hope it helps, Cheers.

Upvotes: 1

adamp
adamp

Reputation: 28932

I hate to tell you this, but it's your hardware.

The touch panel used in the Nexus One (which I believe is the same hardware used in the HTC Desire) is known for this particular artifact. We did some work to alleviate the "jumps to other finger's axis" problem around the ACTION_POINTER_UP/DOWN events for Android 2.2 by dropping some detectable bad events, but the problem still persists when the pointers get close along one axis. This panel is also known for randomly reversing X and Y coordinate data; two points (x0, y0) and (x1, y1) become (x0, y1) and (x1, y0). Sadly there's only so much you can do when the "real" data is gone by the time Android itself gets hold of it.

This isn't the only panel in the wild that has dodgy multitouch capabilities. To tell at runtime if you have a screen capable of precise multitouch data reporting without issues like this, use PackageManager to check for FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT. If you don't have this feature available you can still do simple things like scale gestures reliably.

Upvotes: 3

Related Questions