Query the exact number of pointers supported by multitouch - android

Is there any way to get programatically the maximum number of individual fingers that the touch screen can detect simultaneously?
I've only been able to find FEATURE_TOUCHSCREEN_MULTITOUCH, FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT and FEATURE_TOUCHSCREEN_MULTITOUCH_JAZZHAND, which only tell me if the hardware supports "2 or more" and "5 or more", respectively.
As far as I've seen, there's no way to get the exact number of fingers supported.
I've been able to find out that my Nexus S supports a maximum of 5 fingers with the following code:
public boolean onTouchEvent(MotionEvent event) {
Log.d("multitouch", event.getPointerCount() + " fingers detected");
return super.onTouchEvent(event);
}
But I'd like to be able to get this data from some sort of environment variable so my users won't have to go through a "detection screen" just to get this information.

You can do so by analizing the event.toString()

Related

How to find touch area for android devices?

Im trying to find touch area for android screen like how much area is covered by any finger,i know about event.getSize() method but its always gives me 0 output and pointerIndex is also 0. how can i find touch area for all android devices as further i also need to calculate touch pressure?
TRY THIS
final View view= findViewById(R.id.view);
view.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Toast.makeText(context, "\"Touch coordinates : \" +\n" +
" String.valueOf(event.getX()) + \"x\" + String.valueOf(event.getY()", Toast.LENGTH_SHORT).show();
return true;
}
});
For your question regarding touch pressure. MotionEvent().getPressure(i) should return a value between 0 and 1 based on the "pressure" placed on the screen. In reality for capacitive screens it is the size of the capacitive object rather than literal pressure, but the concept is almost the same for fingers (fingers are squishy). Ranges higher than one may be returned depending on the calibration of the touchscreen.
If your screen is only returning 0 or 1, try testing on another device. Perhaps your screens driver simply does not return those values.Below link can be helpful for you
https://developer.android.com/reference/android/view/MotionEvent.html#getPressure(int)
http://android-er.blogspot.com/2014/05/get-touch-pressure.html

Normalising accelerometer data

I've been trying for a long time to try to figure out why the way my game plays varies slightly differently on different devices (i.e.: some devices seem to be more sensitive than others with regards to the accelerometers).
I've just noticed that the when tilting my devices and logging the output, on one device, the output seems to be between -9.5 and + 9.5 and on another, it appears to be around -10.7 to +10.7.
I'm using this returned data to move my sprite.
#Override
public void onSensorChanged(SensorEvent event) {
tiltAmount = event.values[device_rotation];
Log.v("Tag", "Value: " + tiltAmount);
}
In the above code example, as I'm tilting the device to the opposite extremes (90° anti-clockwise and 90° clockwise), I'm getting the ranges described above.
I would like this data to be consistent across device.
Does anyone have any idea how I could normalise it?
It seems like you have extreme values defined. In that scenario, you could divide a given value by the total dynamic range to get normalized value:
NormalizedValue = x / (Highest - Lowest)

Counting pointers correctly with getPointerCount()

i'm writing an Android app for a school project that performs a different action depending on how many fingers the user taps the screen with.
Right now this action is just to display the number of pointers detected as a toast.
I'm using the getPointerCount() method, but for some reason, I get multiple toasts. For example, a three finger tap gives me toasts for two and three finger taps, a four finger tap will give me toasts for two, three and four finger taps, and so on.
I cannot for the life of me figure out why this is. A four finger tap should display ONE toast saying "4", not cycle through 2, 3 and 4! Any help would be greatly appreciated.
public boolean onTouchEvent(MotionEvent event)
{
int action = event.getAction();
switch(action & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_POINTER_DOWN:
int count = event.getPointerCount();
if (count == 2) {
finish();
}
else if (count == 4) {
Toast.makeText(this, String.valueOf(count), Toast.LENGTH_SHORT).show();
}
else if (count == 3) {
Toast.makeText(this, String.valueOf(count), Toast.LENGTH_SHORT).show();
}
break;
}
return true;
}
P.S, I have tried moving the code outside of the switch statement, and bizarrely , this causes the toasts to count up AND down!
You're thinking of the taps as discrete events, but Android MotionEvents are delivered as a stream. In order to get an ACTION_POINTER_DOWN with three fingers, it is required that you get an action pointer down with two fingers first. (If you think about it, all three fingers do not go down at the exact same time, even if this was possible you wouldn't receive them that way).
If you log every motion event with
Log.i("test", event.toString());
You should be able to see the sequence of events you are receiving, and better understand how to deal with them.

Is there any way to check if device supports stylus input?

I want to show an menu item only if the device supports the stylus for input.
Unfortunately i've found nothing check if the device or the display supports the stylus/Spen for input.
Edit:
I can distinguish between Stylus and Finger after a MotionEvent is triggered using event.getToolType().
If the tooltype is TOOL_TYPE_STYLUS i can be sure that it supports the stylus.
If not i can guess if there is a pressure > 0 (relating to how to detect if the screen is capacitive or resistive in an Android device?)
But i would like to know it in the onCreate method of my activity.
Following is somehow not supported and does not work for me.
Configuration config = getResources().getConfiguration();
if (config.touchscreen == Configuration.TOUCHSCREEN_STYLUS)
Toast.makeText(this, "TOUCHSCREEN_STYLUS", Toast.LENGTH_SHORT).show();
You can detect S-Pen and other stylus's pretty reliably via InputManager:
boolean sPen = false;
if(Build.VERSION.SDK_INT > 15) {
InputManager inptmgr = (InputManager)getSystemService(INPUT_SERVICE);
int[] inputs = inptmgr.getInputDeviceIds();
for(int i = 0;i<inputs.length;i++) {
if(inptmgr.getInputDevice(inputs[i]).getName().toLowerCase().contains("pen")) sPen = true;
}
}
Usually devices will register with their appropriate names contained in them, for example, "Bluetooth Mouse", "Logitech USB Keyboard" or "E_Pen"
Here you go (from the Android documentation) - seems to only be supported in 4.0 and up though.
http://developer.android.com/about/versions/android-4.0.html
Android now provides APIs for receiving input from a stylus input
device such as a digitizer tablet peripheral or a stylus-enabled touch
screen.
Stylus input operates in a similar manner to touch or mouse input.
When the stylus is in contact with the digitizer, applications receive
touch events just like they would when a finger is used to touch the
display. When the stylus is hovering above the digitizer, applications
receive hover events just like they would when a mouse pointer was
being moved across the display when no buttons are pressed.
Your application can distinguish between finger, mouse, stylus and
eraser input by querying the “tool type" associated with each pointer
in a MotionEvent using getToolType(). The currently defined tool types
are: TOOL_TYPE_UNKNOWN, TOOL_TYPE_FINGER, TOOL_TYPE_MOUSE,
TOOL_TYPE_STYLUS, and TOOL_TYPE_ERASER. By querying the tool type,
your application can choose to handle stylus input in different ways
from finger or mouse input.
Your application can also query which mouse or stylus buttons are
pressed by querying the “button state" of a MotionEvent using
getButtonState(). The currently defined button states are:
BUTTON_PRIMARY, BUTTON_SECONDARY, BUTTON_TERTIARY, BUTTON_BACK, and
BUTTON_FORWARD. For convenience, the back and forward mouse buttons
are automatically mapped to the KEYCODE_BACK and KEYCODE_FORWARD keys.
Your application can handle these keys to support mouse button based
back and forward navigation.
In addition to precisely measuring the position and pressure of a
contact, some stylus input devices also report the distance between
the stylus tip and the digitizer, the stylus tilt angle, and the
stylus orientation angle. Your application can query this information
using getAxisValue() with the axis codes AXIS_DISTANCE, AXIS_TILT, and
AXIS_ORIENTATION.
The answer of #Aaron Gillion is looking to be working, but trusting detection of a function to a name looks non-100%-reliable.
I checked out the standard Android InputDevice and found out some an interesting function supportsSource which allows if the device supports e.g. SOURCE_STYLUS. Here an example:
if (Build.VERSION_CODES.JELLY_BEAN <= Build.VERSION.SDK_INT) {
InputManager im = (InputManager) context.getSystemService(INPUT_SERVICE);
for (int id : im.getInputDeviceIds()) {
InputDevice inputDevice = im.getInputDevice(id);
if (
inputDevice.supportsSource(InputDevice.SOURCE_STYLUS) ||
inputDevice.supportsSource(InputDevice.SOURCE_BLUETOOTH_STYLUS)
)
return true;
}
}
return false;
If you pursue lower SDK you can inline supportsSource function, which is ridiculously simple:
public boolean supportsSource(int source) {
return (mSources & source) == source;
}
And constants:
added in 23 - SOURCE_BLUETOOTH_STYLUS = 0x00008000 | SOURCE_STYLUS
added in 14 - SOURCE_STYLUS = 0x00004000 | SOURCE_CLASS_POINTER
added in 9 - SOURCE_CLASS_POINTER = 0x00000002 from 9
I've tested the code on a couple of devices and it is detecting the stylus correctly. I would appreciated if you can share your results of detecting the stylus on non-Samsung devices.
I don't think there is any such thing as to detect stylus input. I would assume that if the device has touch capability, it can also respond to a stylus. Android doesn't specifically support stylus input, as far as I know.

Determining where someone touches on an image

This is a basic question that leads into others down the line.
I am looking at expanding my app to have a image of a target (3 circles) and I want the user to be able to touch on the target image where they hit. Then the app determines where the user clicked.
Not progressed down this line of development yet and do not know where the best place to start / learn. Has anyone got any tips / websites / examples that I can be pointed at to get the ball rolling
Thanks
UPDATED
What I am trying to do and I have no knowledge on where to start
Draw a target on a canvas, 3 circles
draw a cross depending where the user clicks on the target
record a score depending on which circle the user clicked in
thanks
You can use an OnTouchListener on your View. That will give you touch events and pass you the coordinates where the finger was at inside of a MotionEvent
Something like this ought to work:
img.setOnTouchListener(new OnTouchListener() {
public void onTouch(View v, MotionEvent me){
Log.i("TAG", "x: " + me.getX() + " y: " + me.getY());
}
});

Categories

Resources