I'm trying to get a list of pointers, whether they are down, and their positions in pixels on the screen, so I can port my desktop game to android. To do so, I have wrote this onTouch handler.
private boolean onTouch(View v, MotionEvent e)
{
final int action = e.getActionMasked();
switch (action)
{
case MotionEvent.ACTION_DOWN:
surfaceView.queueEvent(() -> postTouchEvent(FINGER_0, true, e.getX(), e.getY()));
break;
case MotionEvent.ACTION_UP:
surfaceView.queueEvent(() -> postTouchEvent(FINGER_0, false, e.getX(), e.getY()));
break;
case MotionEvent.ACTION_POINTER_DOWN:
case MotionEvent.ACTION_POINTER_UP:
{
final int index = e.getActionIndex();
final int finger = index + 1;
if (finger < FINGER_1 || finger > FINGER_9)
break;
final boolean isDown = action == MotionEvent.ACTION_POINTER_DOWN;
surfaceView.queueEvent(() -> postTouchEvent(finger, isDown, e.getX(), e.getY()));
}
break;
case MotionEvent.ACTION_MOVE:
for (int i = 0; i < e.getPointerCount(); i++)
{
final int finger = i + 1;
if (finger < FINGER_0 || finger > FINGER_9)
break;
surfaceView.queueEvent(() ->
postTouchEvent(finger, true, e.getX(finger - 1), e.getY(finger - 1)));
}
for (int i = e.getPointerCount(); i < FINGER_9; i++)
{
final int finger = i + 1;
surfaceView.queueEvent(() -> postTouchEvent(finger, false, 0, 0));
}
break;
}
return true;
}
The issue is however with the ACTION_MOVE
event, I'm getting the an IllegalArgumentException
for accessing my index id's. This is happening only when I tap three or more fingers on the screen at once, but it is still an issue. The exception is as follows.
FATAL EXCEPTION: GLThread 61026
Process: com.shc.silenceengine.tests.android, PID: 23077
java.lang.IllegalArgumentException: pointerIndex out of range
at android.view.MotionEvent.nativeGetAxisValue(Native Method)
at android.view.MotionEvent.getX(MotionEvent.java:2014)
at com.shc.silenceengine.backend.android.AndroidInputDevice.lambda$onTouch$14(AndroidInputDevice.java:228)
at com.shc.silenceengine.backend.android.AndroidInputDevice.access$lambda$6(AndroidInputDevice.java)
at com.shc.silenceengine.backend.android.AndroidInputDevice$$Lambda$7.run(Unknown Source)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1462)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1239)
I'm not sure why I'm getting the error because I'm doing the for loop only up to e.getPointerCount()
so there is no chance of the index going out of the code.
I don't want to track the pointer ID's, I just want a raw list of pointers and these events make up in my engine list to the next frame.
Anyone point me where the issue is?
You are calling e.getX()
and e.getY()
from a separate (later) thread - it's likely that the MotionEvent
object's internal state has changed between the onTouch()
callback and execution of the thread.
You should only assume the MotionEvent object is valid during the onTouch()
method and retrieve the values for getX()
and getY()
to pass to the thread before the method exits.