title: Detecting touch coordinates in Android
body: <p>I want to detect touch coordinates, but not coordinates of the point of touch. For example, if I touch the screen, I want that all area of finger, which touched the screen was painted. Methods getX() and getY() of touchEvent gave me only coordinates of one point, as I understand. How can I solve my problem?</p>
  
  <p>Now I have application, where user can only draw points or lines, but I want, that size and form of lines of points was like size and form of finger, which touched the screen.</p>
  
  <p>Code:</p>
  
  <pre><code>@Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      requestWindowFeature(Window.FEATURE_NO_TITLE);
      dv = new DrawingView(this);
      setContentView(dv);
      mPaint = new Paint();
      mPaint.setAntiAlias(true);
      mPaint.setDither(true);
      mPaint.setColor(Color.BLACK);
      mPaint.setStyle(Paint.Style.STROKE);
      mPaint.setStrokeJoin(Paint.Join.ROUND);
      mPaint.setStrokeCap(Paint.Cap.ROUND);
      mPaint.setStrokeWidth(120);  
  }
  
  public class DrawingView extends View {
  
      public int width;
      public  int height;
      private Bitmap  mBitmap;
      private Canvas  mCanvas;
      private Path    mPath;
      private Paint   mBitmapPaint;
      Context context;
      private Paint circlePaint;
      private Path circlePath;
  
      public DrawingView(Context c) {
          super(c);
          context=c;
          mPath = new Path();
          mBitmapPaint = new Paint(Paint.DITHER_FLAG);  
          circlePaint = new Paint();
          circlePath = new Path();
          circlePaint.setAntiAlias(true);
          circlePaint.setColor(Color.BLUE);
          circlePaint.setStyle(Paint.Style.STROKE);
          circlePaint.setStrokeJoin(Paint.Join.MITER);
          circlePaint.setStrokeWidth(4f); 
  
  
      }
  
      @Override
      protected void onSizeChanged(int w, int h, int oldw, int oldh) {
          super.onSizeChanged(w, h, oldw, oldh);
  
          mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
          mCanvas = new Canvas(mBitmap);
  
      }
      @Override
      protected void onDraw(Canvas canvas) {
          super.onDraw(canvas);
  
          canvas.drawBitmap( mBitmap, 0, 0, mBitmapPaint);
  
          canvas.drawPath( mPath,  mPaint);
  
          canvas.drawPath( circlePath,  circlePaint);
      }
  
      private float mX, mY;
      private static final float TOUCH_TOLERANCE = 4;
  
      private void touch_start(float x, float y) {
          mPath.reset();
          mPath.moveTo(x, y);
          mX = x;
          mY = y;
      }
      private void touch_move(float x, float y) {
          float dx = Math.abs(x - mX);
          float dy = Math.abs(y - mY);
          if (dx &gt;= TOUCH_TOLERANCE || dy &gt;= TOUCH_TOLERANCE) {
              mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
              mX = x;
              mY = y;
  
              circlePath.reset();
              circlePath.addCircle(mX, mY, 30, Path.Direction.CW);
          }
      }
      private void touch_up() {
          mPath.lineTo(mX, mY);
          circlePath.reset();
          // commit the path to our offscreen
          mCanvas.drawPath(mPath,  mPaint);
          // kill this so we don't double draw
          mPath.reset();
      }
  
      @Override
      public boolean onTouchEvent(MotionEvent event) {
          mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
          float x = event.getX();
          float y = event.getY();
  
          switch (event.getAction()) {
          case MotionEvent.ACTION_DOWN:
              touch_start(x, y);
              invalidate();
              break;
          case MotionEvent.ACTION_MOVE:
              touch_move(x, y);
              invalidate();
              break;
          case MotionEvent.ACTION_UP:
              touch_up();
              invalidate();
              break;
          }
          return true;
      }  
  }
  </code></pre>