here is in the original text from the post, this explains how to make
the bug occur:
1) Touch screen with finger 1 and start doodling
2) Without removing finger 1, touch screen with finger 2 and
start doodling
3) Remove finger 1 from the screen (without removing finger 2)
4) Replace finger 1 on the screen and start doodling again
(never remove finger 2)
5) Voila, you will see the bug. The drawn lines for finger 1
will suddeny connect to finger 2.
This is because there is a bug when the first finger is placed back
down again, the event only has points for the wrong finger! Even
though finger 1 went back down at a new location, the code thinks for
some reason that finger 2 is the one that went back down (but it never
went up).
-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