Jun 21, 2011

Detect Touch Event part III - get touch pressure and size

The MotionEvent object retured with pressure and size of touching. It can be get using getPressure() and getSize() method. The code in last post "Detect Touch Event, test on Custom View; part II" is further modified to show touching pressure and size in color and radius.

get touch pressure and size of MotionEvent

package com.TestSingleTouch;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;

public class TestSingleTouch extends Activity {

public class TouchView extends View {

private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private float x, y;
boolean touching = false;

float pressure = 0; //Touch pressure
float size = 0; //Touch size
final static float PRESET_PRESSURE = 0xFF;
final static float PRESET_SIZE = 300;

public TouchView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}

@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
if(touching){

//paint.setStyle(Paint.Style.STROKE);
//paint.setStrokeWidth(1);
//paint.setColor(Color.WHITE);
//canvas.drawCircle(x, y, 50f, paint);

paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setStrokeWidth(1);
paint.setColor(0xFF000000
+ ((int)(PRESET_PRESSURE * pressure) <<16)
+ ((int)(PRESET_PRESSURE * pressure) << 8)
+ (int)(PRESET_PRESSURE * pressure));
canvas.drawCircle(x, y, (PRESET_SIZE * size), paint);
}
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
MeasureSpec.getSize(heightMeasureSpec));
}

@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub

pressure = event.getPressure();
if(pressure > 1){
pressure = 1;
}

size =event.getSize();

String act;

int action = event.getAction();
switch(action){
case MotionEvent.ACTION_MOVE:
act = "ACTION_MOVE\n";
x = event.getX();
y = event.getY();

touching = true;
break;
case MotionEvent.ACTION_DOWN:
act = "ACTION_DOWN\n";
x = event.getX();
y = event.getY();

touching = true;
break;
case MotionEvent.ACTION_UP:
act = "ACTION_UP\n";
touching = false;
break;
default:
act = "XXX\n";
touching = false;
}

act += event.toString();
textView.setText(act);

invalidate();
return true;
}

}

TextView textView;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(new TouchView(this));

textView = new TextView(this);
textView.setText("Waiting");
TouchView touchView = new TouchView(this);
LinearLayout mainScreen = new LinearLayout(this);
mainScreen.setOrientation(LinearLayout.VERTICAL);
mainScreen.addView(textView);
mainScreen.addView(touchView);
setContentView(mainScreen);

}

}


Next:
- Detect Touch Event part IV - get touch area



7 comments:

  1. Hello,

    Are there multi-touch devices which can really report pressure ? Isn't the pressure infered from size ?

    By the way, is there a list of Android devices able to report size and/or pressure ?

    ReplyDelete
  2. I tested it on Nexus One, both pressure and size can be reported. But, not accuracy. For example: If I touch lightly, report 0.2xxx..., with more pressure, it report 0.7xx...

    ReplyDelete
  3. I am using a Samsung Galaxy S to run your code and the pressure value does not change. Any thoughts?

    ReplyDelete
  4. Hi there, You're code works well on my phone but I;d like to know to to achieve the fallowing: How to draw the actual finger form instead of circle? In other words how to collect all touched screen pixel coordinates and set the color for each pixel to white for example!

    ReplyDelete
  5. @w3boulevard : you can nearly do that by using AXIS_TOUCH_MAJOR and AXIS_TOUCH_MINOR in a MotionEvent since API 12, which are ellipse definition for a pointer (Android represent each pointer by an ellipse)
    Then you can draw an ellipse instead of a circle.

    see
    http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_TOUCH_MAJOR
    and
    http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_TOUCH_MINOR

    ReplyDelete

Infolinks In Text Ads