Sorry,  perhaps I was not clear in the description what the bug is.  I
will attempt to explain it in better detail here.

When you perform the following touch pattern:

1) place finger 1 down
2) place finger 2 down
3) remove finger 1
4) place finger 1 back down again

The ACTION_POINTER_DOWN event that is generated during step 4 returns
the incorrect X and Y location for where the event occurred.  In fact,
the X, and Y that is returned is the X and Y location for the other
finger.  Searching the entire history of the motionevent shows that
there is no record of the X, Y for finger 1.  Running the above code
illustrates the problem and makes it obvious.  As when you replace
finger 1 and start to move it, it suddenly draws a line from finger 2
to finger 1, connecting the two, thus illustrating the bug.  If you
run the code and observe the output when performing the above actions,
you will see clearly the problem.

I have debugged this and looked at every point in every motionevent
that is captured, and during step 4, the X, Y locations for finger 1
are not anywhere to be found.  Ot is only during an ACTION_MOVE that
new X, Y values for finger 1 appear.

As an aside, if you then remove finger 1 again, the ACTION_POINTER_UP
event tells you that finger 2 is coming up according to the ID.  This
is also a bug.

I hope this helps.  I can try to post screens of this if that will
also help.

-Colin

On Jan 15, 2:35 pm, rollbak <[email protected]> wrote:
> Can you please explain which the issue is?
>
> On Jan 15, 1:09 pm, Mirmathrax <[email protected]> wrote:
>
> > Multi-touch API is bugged (at least on Motorola Droid). Here is a
> > method to reproduce the error for analysis:
>
> > 1)  Create a new android project in Eclipse with the following fields:
>
> >  Project name:           PointerLocation
> >  Build target:              Android 2.0.1
> >  Application Name:     PointerLocation
> >  Package Name:        com.example.pointerlocation
> >  Create Activity:         PointerLocation
>
> > 2)  Copy the following code and paste this into the
> > PointerLocation.java file that is automatically created
>
> > /*
> >  * Copyright (C) 2007 The Android Open Source Project
> >  *
> >  * Licensed under the Apache License, Version 2.0 (the "License");
> >  * you may not use this file except in compliance with the License.
> >  * You may obtain a copy of the License at
> >  *
> >  *      http://www.apache.org/licenses/LICENSE-2.0
> >  *
> >  * Unless required by applicable law or agreed to in writing, software
> >  * distributed under the License is distributed on an "AS IS" BASIS,
> >  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> > implied.
> >  * See the License for the specific language governing permissions and
> >  * limitations under the License.
> >  */
>
> > package com.example.pointerlocation;
>
> > import android.app.Activity;
> > import android.content.Context;
> > import android.graphics.Canvas;
> > import android.graphics.Paint;
> > import android.graphics.Paint.FontMetricsInt;
> > import android.os.Bundle;
> > import android.util.Log;
> > import android.view.MotionEvent;
> > import android.view.ViewConfiguration;
> > import android.view.WindowManager;
> > import android.view.VelocityTracker;
> > import android.view.View;
>
> > import java.util.ArrayList;
>
> > /**
> >  * Demonstrates wrapping a layout in a ScrollView.
> >  *
> >  */
> > public class PointerLocation extends Activity {
> >     @Override
> >     protected void onCreate(Bundle icicle) {
> >         super.onCreate(icicle);
> >         setContentView(new MyView(this));
>
> >         // Make the screen full bright for this activity.
> >         WindowManager.LayoutParams lp = getWindow().getAttributes();
> >         lp.screenBrightness = 1.0f;
> >         getWindow().setAttributes(lp);
> >     }
>
> >     public static class PointerState {
> >         private final ArrayList<Float> mXs = new ArrayList<Float>();
> >         private final ArrayList<Float> mYs = new ArrayList<Float>();
> >         private boolean mCurDown;
> >         private int mCurX;
> >         private int mCurY;
> >         private float mCurPressure;
> >         private float mCurSize;
> >         private int mCurWidth;
> >         private VelocityTracker mVelocity;
> >     }
>
> >     public class MyView extends View {
> >         private final ViewConfiguration mVC;
> >         private final Paint mTextPaint;
> >         private final Paint mTextBackgroundPaint;
> >         private final Paint mTextLevelPaint;
> >         private final Paint mPaint;
> >         private final Paint mTargetPaint;
> >         private final Paint mPathPaint;
> >         private final FontMetricsInt mTextMetrics = new FontMetricsInt
> > ();
> >         private int mHeaderBottom;
> >         private boolean mCurDown;
> >         private int mCurNumPointers;
> >         private int mMaxNumPointers;
> >         private final ArrayList<PointerState> mPointers
> >                  = new ArrayList<PointerState>();
>
> >         public MyView(Context c) {
> >             super(c);
> >             mVC = ViewConfiguration.get(c);
> >             mTextPaint = new Paint();
> >             mTextPaint.setAntiAlias(true);
> >             mTextPaint.setTextSize(10
> >                     * getResources().getDisplayMetrics().density);
> >             mTextPaint.setARGB(255, 0, 0, 0);
> >             mTextBackgroundPaint = new Paint();
> >             mTextBackgroundPaint.setAntiAlias(false);
> >             mTextBackgroundPaint.setARGB(128, 255, 255, 255);
> >             mTextLevelPaint = new Paint();
> >             mTextLevelPaint.setAntiAlias(false);
> >             mTextLevelPaint.setARGB(192, 255, 0, 0);
> >             mPaint = new Paint();
> >             mPaint.setAntiAlias(true);
> >             mPaint.setARGB(255, 255, 255, 255);
> >             mPaint.setStyle(Paint.Style.STROKE);
> >             mPaint.setStrokeWidth(2);
> >             mTargetPaint = new Paint();
> >             mTargetPaint.setAntiAlias(false);
> >             mTargetPaint.setARGB(255, 0, 0, 192);
> >             mPathPaint = new Paint();
> >             mPathPaint.setAntiAlias(false);
> >             mPathPaint.setARGB(255, 0, 96, 255);
> >             mPaint.setStyle(Paint.Style.STROKE);
> >             mPaint.setStrokeWidth(1);
>
> >             PointerState ps = new PointerState();
> >             ps.mVelocity = VelocityTracker.obtain();
> >             mPointers.add(ps);
> >         }
>
> >         @Override
> >         protected void onMeasure(int widthMeasureSpec, int
> > heightMeasureSpec) {
> >             super.onMeasure(widthMeasureSpec, heightMeasureSpec);
> >             mTextPaint.getFontMetricsInt(mTextMetrics);
> >             mHeaderBottom = -mTextMetrics.ascent+mTextMetrics.descent
> > +2;
> >             Log.i("foo", "Metrics: ascent=" + mTextMetrics.ascent
> >                     + " descent=" + mTextMetrics.descent
> >                     + " leading=" + mTextMetrics.leading
> >                     + " top=" + mTextMetrics.top
> >                     + " bottom=" + mTextMetrics.bottom);
> >         }
>
> >         @Override
> >         protected void onDraw(Canvas canvas) {
> >             final int w = getWidth();
> >             final int itemW = w/7;
> >             final int base = -mTextMetrics.ascent+1;
> >             final int bottom = mHeaderBottom;
>
> >             final int NP = mPointers.size();
>
> >             if (NP > 0) {
> >                 final PointerState ps = mPointers.get(0);
> >                 canvas.drawRect(0, 0, itemW-1,
> > bottom,mTextBackgroundPaint);
> >                 canvas.drawText("P: " + mCurNumPointers + " / " +
> > mMaxNumPointers,
> >                         1, base, mTextPaint);
>
> >                 final int N = ps.mXs.size();
> >                 if ((mCurDown && ps.mCurDown) || N == 0) {
> >                     canvas.drawRect(itemW, 0, (itemW * 2) - 1, bottom,
> > mTextBackgroundPaint);
> >                     canvas.drawText("X: " + ps.mCurX, 1 + itemW, base,
> > mTextPaint);
> >                     canvas.drawRect(itemW * 2, 0, (itemW * 3) - 1,
> > bottom, mTextBackgroundPaint);
> >                     canvas.drawText("Y: " + ps.mCurY, 1 + itemW * 2,
> > base, mTextPaint);
> >                 } else {
> >                     float dx = ps.mXs.get(N-1) - ps.mXs.get(0);
> >                     float dy = ps.mYs.get(N-1) - ps.mYs.get(0);
> >                     canvas.drawRect(itemW, 0, (itemW * 2) - 1, bottom,
> >                             Math.abs(dx) < mVC.getScaledTouchSlop()
> >                             ? mTextBackgroundPaint : mTextLevelPaint);
> >                     canvas.drawText("dX: " + String.format("%.1f",
> > dx), 1 + itemW, base, mTextPaint);
> >                     canvas.drawRect(itemW * 2, 0, (itemW * 3) - 1,
> > bottom,
> >                             Math.abs(dy) < mVC.getScaledTouchSlop()
> >                             ? mTextBackgroundPaint : mTextLevelPaint);
> >                     canvas.drawText("dY: " + String.format("%.1f",
> > dy), 1 + itemW * 2, base, mTextPaint);
> >                 }
>
> >                 canvas.drawRect(itemW * 3, 0, (itemW * 4) - 1, bottom,
> > mTextBackgroundPaint);
> >                 int velocity = ps.mVelocity == null ? 0 : (int)
> > (ps.mVelocity.getXVelocity() * 1000);
> >                 canvas.drawText("Xv: " + velocity, 1 + itemW * 3,
> > base, mTextPaint);
>
> >                 canvas.drawRect(itemW * 4, 0, (itemW * 5) - 1, bottom,
> > mTextBackgroundPaint);
> >                 velocity = ps.mVelocity == null ? 0 : (int)
> > (ps.mVelocity.getYVelocity() * 1000);
> >                 canvas.drawText("Yv: " + velocity, 1 + itemW * 4,
> > base, mTextPaint);
>
> >                 canvas.drawRect(itemW * 5, 0, (itemW * 6) - 1, bottom,
> > mTextBackgroundPaint);
> >                 canvas.drawRect(itemW * 5, 0, (itemW * 5) +
> > (ps.mCurPressure * itemW) - 1,
> >                         bottom, mTextLevelPaint);
> >                 canvas.drawText("Prs: " + String.format("%.2f",
> > ps.mCurPressure), 1 + itemW * 5,
> >                         base, mTextPaint);
>
> >                 canvas.drawRect(itemW * 6, 0, w, bottom,
> > mTextBackgroundPaint);
> >                 canvas.drawRect(itemW * 6, 0, (itemW * 6) +
> > (ps.mCurSize * itemW) - 1,
> >                         bottom, mTextLevelPaint);
> >                 canvas.drawText("Size: " + String.format("%.2f",
> > ps.mCurSize), 1 + itemW * 6,
> >                         base, mTextPaint);
> >             }
>
> >             for (int p=0; p<NP; p++) {
> >                 final PointerState ps = mPointers.get(p);
>
> >                 if (mCurDown && ps.mCurDown) {
> >                     canvas.drawLine(0, (int)ps.mCurY, getWidth(), (int)
> > ps.mCurY, mTargetPaint);
> >                     canvas.drawLine((int)ps.mCurX, 0, (int)ps.mCurX,
> > getHeight(), mTargetPaint);
> >          
>
> ...
>
> read more »
-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to