MotionEvent.Action_UP is always called - android

Here is the code for my onTouchEvent(MotionEvent event):
#Override
public boolean onTouchEvent(MotionEvent event){
int action = event.getAction();
int x = Math.round(event.getX());
int y = Math.round(event.getY());
//play is an imageView
int viewLeft = play.getLeft();
int viewRight = play.getRight();
int viewTop = play.getTop();
int viewBottom = play.getBottom();
boolean onPoint = false;
switch (action) {
case MotionEvent.ACTION_DOWN:
//Checks if the touched area falls within the imageView play
if ((x >= viewLeft && x <= viewRight) && (y >= viewTop && y <= viewBottom)) {
onPoint = true;
play.setImageResource(R.drawable.playyellow);
}
case MotionEvent.ACTION_UP:
//if the finger is lifed on the imageView, the intent is called
play.setImageResource(R.drawable.play1);
if (onPoint) {
if ((x >= viewLeft && x <= viewRight) && (y >= viewTop && y <= viewBottom)) {
Intent i = new Intent(this, InGame.class);
startActivity(i);
}
}
}
return true;
}
The problem here is that ACTION_UP is always called, regardless of whether or not I actually lift my finger off the screen. I ran it in debugging mode while placing a breakpoint on case MotionEvent.ACTION_UP, and when I pressed down (and didn't release), it got called. Can someone explain why this happens?

I analyzed your code and I think it is just because you did not insert break in between Action_Down and Action_Up cases.
try the following code.....
switch (action) {
case MotionEvent.ACTION_DOWN:
//Checks if the touched area falls within the imageView play
if ((x >= viewLeft && x <= viewRight) && (y >= viewTop && y <= viewBottom)) {
onPoint = true;
play.setImageResource(R.drawable.playyellow);
}
break;
case MotionEvent.ACTION_UP:
//if the finger is lifed on the imageView, the intent is called
play.setImageResource(R.drawable.play1);
if (onPoint) {
if ((x >= viewLeft && x <= viewRight) && (y >= viewTop && y <= viewBottom)) {
Intent i = new Intent(this, InGame.class);
startActivity(i);
}
}
}
return true;
I hope it will help you...

Related

Calling TextView setText() from onTouchListener stucks UI

Here is my sample code:
#Override
public boolean onTouchEvent(MotionEvent e) {
float center = mScrubberX + mScrubberWidth / 2;
float handleLeft = center - HANDLE_WIDTH;
float handleRight = center + HANDLE_WIDTH;
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
if (e.getX() > handleLeft && e.getX() < handleRight) {
mActionDown = true;
mActionDownX = e.getX() - mScrubberX;
}
break;
case MotionEvent.ACTION_MOVE:
float newLeft = e.getX() - mActionDownX;
float newRight = newLeft + mScrubberWidth;
if (mActionDown && !mIsStreaming) {
if (newLeft > mScrubberContainer.getLeft() &&
newRight < mScrubberContainer.getRight()) {
mScrubberX = e.getX() - mActionDownX;
textView.setText(""+mScrubberX)
} else if (newRight < mScrubberContainer.getRight()) {
mScrubberX = mScrubberContainer.getLeft();
} else if (newLeft > mScrubberContainer.getLeft()) {
mScrubberX = mScrubberContainer.getRight() - mScrubberWidth;
}
}
break;
case MotionEvent.ACTION_UP:
mActionDown = false;
break;
default:
//Do nothing
}
invalidate();
return true;
}
Please check line "textView.setText(""+mScrubberX)" struck the UI. I have tried putting this inside Handler, Asynctask.executor, runOnUIThread but nothing worked.
Please suggest some solution to get rid of this issue.

Detech if user has touched edges of a View

I am trying to create a game, and I have a circle now I want to detect if a user has touched the edges of the circle.
It does need to be code even an explanation on how to do it would be great, but if there would be code it would be appreciated :D
This is the example:
Visual Aid on what I am trying to achieve.
Basically I want to detect if the user has touched the TOP LEFT, TOP RIGHT, BOTTOM LEFT, and BOTTOM RIGHT portions of the circle.
This is what I have done so far:
#Override
public boolean onTouchEvent(MotionEvent event){
int x=(int)event.getX();
int y=(int)event.getY();
if (event.getAction() == MotionEvent.ACTION_DOWN){
if (x < boxX){
touchDirection = "LEFT";
}
else if (x > boxX){
touchDirection = "RIGHT";
}
//NOT WORKING
else if (x < boxX && y > boxY){
touchDirection = "TOP LEFT";
}
else if (x > boxX && y > boxY){
touchDirection = "TOP RIGHT";
}
}
Thanks in advance for any help! :D
#Override
public boolean onTouchEvent(MotionEvent event){
int x=(int)event.getX();
int y=(int)event.getY();
if (event.getAction() == MotionEvent.ACTION_DOWN){
if(y > boxY) touchDirection.append("TOP");
else touchDirection.append("BOTTOM");
if (x < boxX){
touchDirection.append(" LEFT");
}
else {
touchDirection.append(" RIGHT");
}
}
Assuming touchDirection is StringBuilder
Sorry I didnt format, it is hard to do in mobile app
if (x < boxX){
touchDirection = "LEFT";
}
else if (x < boxX && y > boxY){
touchDirection = "TOP LEFT";
}
First condition will never allow you to check whatever you've written in else if block. Whether it finds x < boxX is true it's not going to the next condition to check 'y > boxY'. My advice is to using only if conditions for each and every case. Like this:
if (x < boxX){
touchDirection = "LEFT";
}
if (x > boxX){
touchDirection = "RIGHT";
}
if (x < boxX && y > boxY){
touchDirection = "TOP LEFT";
}
if (x > boxX && y > boxY){
touchDirection = "TOP RIGHT";
}
PS: As I can't replicate your case my answer is based on unimplemented logic. Hope this helps.
Hey guys I found my answer already, thanks to user5954246 and WS Ayan for providing help in finding the answer to my problem.
Basically this is what I did:
#Override
public boolean onTouchEvent(MotionEvent event){
int x=(int)event.getX();
int y=(int)event.getY();
if (event.getAction() == MotionEvent.ACTION_DOWN){
if (x <= boxX && y >= boxY){
touchDirection = "BOTTOM LEFT";
}
if (x >= boxX && y >= boxY){
touchDirection = "BOTTOM RIGHT";
}
if (x <= boxX && y <= boxY){
touchDirection = "TOP LEFT";
}
if (x >= boxX && y <= boxY){
touchDirection = "TOP RIGHT";
}
}

Dragged ImageView, knowing when it's in an X Y area

I have a draggable image and I'm trying to get it so that if it goes within an X Y region of the screen that an event happens.
So far I can detect when I move a finger through the region but not when it is dragging the image.
The code so far: - this code works for the finger
public boolean onTouchEvent(MotionEvent ev) {
int x = (int) ev.getX();
int y = (int) ev.getY();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
if (x >= 370 && x <= 500 && y >= 250 && y <= 420) {
Log.i(null, "--- Region 1 initiated ---");
}
What I've tried: - but when I try to adapt it to the image...
public boolean onDrag(View layoutview, DragEvent dragevent) {
int action = dragevent.getAction();
View getid = findViewById(R.id.image);
int x1 = (int) getid.getX();
int y1 = (int) getid.getY();
if (action == MotionEvent.ACTION_MOVE) {
if (x1 >= 370 && x1 <= 500 && y1 >= 250 && y1 <= 420) {
Log.i(null, "--- Region 1 initiated by image---");
}
}
...nothing happens. The logcat doesn't show the message. Does anyone know where I'm going wrong or if there's a way of doing this.
Some illustrations, sometimes my description of the problem is pretty bad:
It took a while but I actually got it working by doing this in onTouch:
final int X = (int) event.getRawX();
final int Y = (int) event.getRawY();
ImageView j = (ImageView) findViewById(R.id.image);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
_xDelta = (int) (X - j.getTranslationX());
_yDelta = (int) (Y - j.getTranslationY());
break;
case MotionEvent.ACTION_UP:
_xDelta = 100;
_yDelta = 100;
break;
case MotionEvent.ACTION_MOVE:
j.setTranslationX(X - _xDelta);
j.setTranslationY(Y - _yDelta);
if (X >= 370 && X <= 500 && Y >= 250 && Y <= 420) {
Log.i(null, "Region 1 initiated");
// Do whatever...
}
There is no MotionEvent.ACTION_MOVE defined in DragEvent class
OnDragListener interface defined the method
abstract boolean onDrag(View v, DragEvent event)
Action are:
ACTION_DRAG_STARTED
ACTION_DRAG_ENTERED
ACTION_DRAG_LOCATION
ACTION_DRAG_EXITED
ACTION_DROP
ACTION_DRAG_ENDED
Please refer to this page for more details

Touch movement in only four directions?

I'm doing a simple match-three game, similar to Bejeweled and I just want to move sprite objects by touching the sprite object and then move it one step in four directions like left, right, up and down. I do this by comparing the X and Y values on Down with the X and Y values on Move. It's working but it's far from perfect! It's so easy to get a wrong value if the movement isn't straight. My questions is: is there a way to improve this and make it better?
I have also looked at gesture, but this seems very complicated to use with a surfaceview that I have.
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.i("test","Down");
touchActionDownX = (int)event.getX();
touchActionDownY = (int)event.getY();
touchActionMoveStatus = true;
gameLoop.touchX = (int)event.getX();
gameLoop.touchY = (int)event.getY();
gameLoop.touchActionDown = true;
break;
case MotionEvent.ACTION_POINTER_UP:
touchActionMoveStatus = true;
break;
case MotionEvent.ACTION_MOVE:
//Log.i("test","Move");
gameLoop.touchActionMove = true;
if(touchActionMoveStatus) {
touchActionMoveX = (int)event.getX();
touchActionMoveY = (int)event.getY();
if(touchActionMoveX < touchActionDownX)
Log.i("test","Move Left");
else if(touchActionMoveX > touchActionDownX)
Log.i("test","Move Right");
else if(touchActionMoveY < touchActionDownY)
Log.i("test","Move Up");
else if(touchActionMoveY > touchActionDownY)
Log.i("test","Move Down");
touchActionMoveStatus = false; // Will be set to true when pointer is up
}
break;
}
// return false;
return true; // This gets the coordinates all the time
}
Try something like this:
#Override
public boolean onTouch(View v, MotionEvent event) {
//You may have to play with the value and make it density dependant.
int threshold = 10;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.i("test","Down");
touchActionDownX = (int)event.getX();
touchActionDownY = (int)event.getY();
touchActionMoveStatus = true;
gameLoop.touchX = (int)event.getX();
gameLoop.touchY = (int)event.getY();
gameLoop.touchActionDown = true;
break;
case MotionEvent.ACTION_POINTER_UP:
touchActionMoveStatus = false;
break;
case MotionEvent.ACTION_MOVE:
//Log.i("test","Move");
gameLoop.touchActionMove = true;
if(touchActionMoveStatus) {
touchActionMoveX = (int)event.getX();
touchActionMoveY = (int)event.getY();
if(touchActionMoveX < (touchActionDownX - threshold) && (touchActionMoveY > (touchActionDownY - threshold)) && (touchActionMoveY (touchActionDownY + threshold))){
Log.i("test","Move Left");//If the move left was greater than the threshold and not greater than the threshold up or down
touchActionMoveStatus = false;
}
else if(touchActionMoveX > (touchActionDownX + threshold) && (touchActionMoveY > (touchActionDownY - threshold)) && (touchActionMoveY < (touchActionDownY + threshold))){
Log.i("test","Move Right");//If the move right was greater than the threshold and not greater than the threshold up or
touchActionMoveStatus = false;
}
else if(touchActionMoveY < (touchActionDownY - threshold) && (touchActionMoveX > (touchActionDownX - threshold)) && (touchActionMoveX < (touchActionDownX + threshold))){
Log.i("test","Move Up");//If the move up was greater than the threshold and not greater than the threshold left or right
touchActionMoveStatus = false;
}
else if(touchActionMoveY > (touchActionDownY + threshold) && (touchActionMoveX > (touchActionDownX - threshold)) && (touchActionMoveX < (touchActionDownX + threshold))){
Log.i("test","Move Down");//If the move down was greater than the threshold and not greater than the threshold left or right
touchActionMoveStatus = false;
}
}
break;
}
// return false;
return true; // This gets the coordinates all the time
}
Or use a ratio:
#Override
public boolean onTouch(View v, MotionEvent event) {
//You may have to play with the value.
//A value of two means you require the user to move twice as
//far in the direction they intend to move than any perpendicular direction.
float threshold = 2.0;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.i("test","Down");
touchActionDownX = (int)event.getX();
touchActionDownY = (int)event.getY();
touchActionMoveStatus = true;
gameLoop.touchX = (int)event.getX();
gameLoop.touchY = (int)event.getY();
gameLoop.touchActionDown = true;
break;
case MotionEvent.ACTION_POINTER_UP:
touchActionMoveStatus = true;
break;
case MotionEvent.ACTION_MOVE:
//Log.i("test","Move");
gameLoop.touchActionMove = true;
if(touchActionMoveStatus) {
touchActionMoveX = (int)event.getX();
touchActionMoveY = (int)event.getY();
// I haven't tested this so you may have a few typos to correct.
float ratioLeftRight = Math.abs(touchActionMoveX - touchActionDownX)/Math.abs(touchActionMoveY - touchActionDownY)
float ratioUpDown = Math.abs(touchActionMoveY - touchActionDownY)/Math.abs(touchActionMoveX - touchActionDownX)
if(touchActionMoveX < touchActionDownX && ratioLeftRight > threshold){
Log.i("test","Move Left");
touchActionMoveStatus = false;
}
else if(touchActionMoveX > touchActionDownX && ratioLeftRight > threshold){
Log.i("test","Move Right");
touchActionMoveStatus = false;
}
else if(touchActionMoveY < touchActionDownY && ratioUpDown > threshold){
Log.i("test","Move Up");
touchActionMoveStatus = false;
}
else if(touchActionMoveY > touchActionDownY && ratioUpDown > threshold){
Log.i("test","Move Down");
touchActionMoveStatus = false;
}
}
break;
}
// return false;
return true; // This gets the coordinates all the time
}
I would choose the dimension with the LARGEST movement and completely ignore the other, for example if the move is x=10 and y=8 then only use the x dimension (i.e. left/right) and vice versa.
Also as noted by Larry McKenzie, using a threshold to ignore smaller movements is a good idea to prevent registering accidental movements that the user did not intend. Tweak the threshold value to someting that feels natural.
Here is some code using your example (only the ACTION_MOVE case):
case MotionEvent.ACTION_MOVE:
//Log.i("test","Move");
gameLoop.touchActionMove = true;
if(touchActionMoveStatus) {
touchActionMoveX = (int)event.getX();
touchActionMoveY = (int)event.getY();
// setup a threshold (below which no movement would occur)
int threshold = 5; /* tweak this as needed */
// first calculate the "delta" movement amounts
int xMove = touchActionMoveX - touchActionDownX;
int yMove = touchActionMoveY - touchActionDownY;
// now find the largest of the two (note that if they
// are equal, x is assumed largest)
if ( Math.abs( xMove ) >= Math.abs( yMove ) ) { /* X-Axis */
if ( xMove >= threshold )
Log.i("test","Move Right");
else if ( xMove <= -threshold )
Log.i("test","Move Left");
}
else { /* Y-Axis */
if ( yMove >= threshold )
Log.i("test","Move Down");
else if ( yMove <= -threshold )
Log.i("test","Move Up");
}
touchActionMoveStatus = false; // Will be set to true when pointer is up
}
}
break;
NOTE: As mentioned in some of the other answers, because multiple events with very small values can occur, it might be best to accumulate (i.e. sum up) the movements UNTIL the threshold is reached - you can use members for this that reset in ACTION_DOWN. Once the threshold is reached (in either dimension) THEN you can perform the checks for which direction.
Alternative Approach
Another way to go about it would be to detect the largest movement in the FIRST ACTION_MOVE event, and then lock all further movements to that dimension. For this you would need to add various state members - these would need to be updated in each state.
Here is a rough example (with only the state tracking):
// members
private boolean axisLock = false; /* Track When Lock is Required */
private boolean axisX = true; /* Axis to Lock (true) for X, (false) for Y */
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// set this state so that ACTION_MOVE knows a lock is required
axisLock = true;
break;
case MotionEvent.ACTION_UP:
// clear the state in case no move was made
axisLock = false;
case MotionEvent.ACTION_MOVE:
// now lock the axis if this is the first move event
if ( axisLock ) {
// this will set whether the locked axis is X (true) or Y (false)
axisX = event.getX() >= event.getY();
// reset the state (to keep the axis locked)
axisLock = false;
}
// at this point you only need to consider the movement for the locked axis
if ( axisX ) {
int movement = (int)event.getX(); /* Get Movement for Locked Axis */
// check for your movement conditions here
}
else {
int movement = (int)event.getY(); /* Get Movement for Locked Axis */
// check for your movement conditions here
}
break;
}
return true;
}
You could add many optimizations to this code, for now it just illustrates the basic idea.
larry had the right idea, i just want to put in a lil fix,
//put this in the wraping class
private static int THRESHOLD = 10;
private static int initX;
private static int initY;
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
initX = (int)event.getX();
initY = (int)event.getY();
break;
case MotionEvent.ACTION_POINTER_UP:
//you can add in some kind of "move back" animation for the item
break;
case MotionEvent.ACTION_MOVE:
if(((int)event.getY - initY) > THRESHOLD){
//move down
break;
}
if(((int)event.getY - initY) > -THRESHOLD){
//move up
break;
}
if(((int)event.getX - initX) > THRESHOLD){
//move right
break;
}
if(((int)event.getX - initX) < -THRESHOLD){
//move left
break;
}
break;
}
}
i didn't test this code, only free write it, but i hope you get my idea :)

android multitouch cant move 2 pointers at same time

I have a weird problem in my game. I'm using 2 joysticks, one for shooting/aiming and one for moving my character. For some reason my multitouch method only registers one movement at a time. The second pointer gets registered when I press down, but my ACTION_MOVE only works for the first pointer. This is weird cus this means it does take more then one pointer, but it cant move more then one pointer at the same time. Ive asked this on gamedev.stackexchange and its been active for about a week, gotten a couple of answer but nothing that makes it work 100%. And I've tried for hours on my own.
Code for onTouch-method:
//global variables
private int movePointerId = -1;
private int shootingPointerId = -1;
public void update(MotionEvent event) {
if (event == null && lastEvent == null) {
return;
} else if (event == null && lastEvent != null) {
event = lastEvent;
} else {
lastEvent = event;
}
// grab the pointer id
int action = event.getAction();
int actionCode = action & MotionEvent.ACTION_MASK;
int actionIndex = event.getActionIndex();
int pid = action >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
int x = (int) event.getX(pid);
int y = (int) event.getY(pid);
String actionString = null;
switch (actionCode)
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
actionString = "DOWN";
try{
if(x > 0 && x < steeringxMesh + (joystick.get_joystickBg().getWidth() * 2)
&& y > yMesh - (joystick.get_joystickBg().getHeight()) && y < panel.getHeight()){
movingPoint.x = x;
movingPoint.y = y;
movePointerId = pid;
dragging = true;
//checks if Im pressing the joystick used for moving
}
else if(x > shootingxMesh - (joystick.get_joystickBg().getWidth()) && x < panel.getWidth()
&& y > yMesh - (joystick.get_joystickBg().getHeight()) && y < panel.getHeight()){
shootingPoint.x = x;
shootingPoint.y = y;
shootingPointerId = pid;
shooting=true;
//checks if Im pressing the joystick used for shooting
}
}catch(Exception e){
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_OUTSIDE:
if( pid == movePointerId ){
movePointerId = -1;
dragging = false;
}
else if( pid == shootingPointerId ){
shootingPointerId = -1;
shooting=false;
}
actionString = "UP";
break;
case MotionEvent.ACTION_MOVE: // this is where my problem is
if( pid == movePointerId ) {
movingPoint.x = x;
movingPoint.y = y;
} else if( pid == shootingPointerId ) {
shootingPoint.x = x;
shootingPoint.y = y;
}
actionString = "MOVE";
break;
}
If I print actionString and pid it shows that when moving, it only checks pid=0, but when i press down ( ACTION_POINTER_DOWN ) I can see that it does register another pid, this is whats really confusing me.
Just to make it more clear, when I press the second pointer down on for example my shooting-stick, it takes the position of where I pressed, even if I'm moving the other joystick at the same time, but it stays there until I let go of the other joystick. Furhter proof that it does register more then 1 touch and more then 1 pid.
Please let me know if you need any further explenation.
I've made a couple of changes to your code, that I believe should solve the problem. Al least it works fine for me ...
//global variables
private int movePointerId = -1;
private int shootingPointerId = -1;
public void update(MotionEvent event) {
if (event == null && lastEvent == null) {
return;
} else if (event == null && lastEvent != null) {
event = lastEvent;
} else {
lastEvent = event;
}
// grab the pointer id
int action = event.getAction();
int actionCode = action & MotionEvent.ACTION_MASK;
int pid = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
int fingerid = event.getPointerId(pid);
//int actionIndex = event.getActionIndex();
//int pid = action >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
int x = (int) event.getX(pid);
int y = (int) event.getY(pid);
String actionString = null;
switch (actionCode)
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
actionString = "DOWN";
try{
if(x > 0 && x < steeringxMesh + (joystick.get_joystickBg().getWidth() * 2)
&& y > yMesh - (joystick.get_joystickBg().getHeight()) && y < panel.getHeight()){
movingPoint.x = x;
movingPoint.y = y;
//movePointerId = pid;
movePointerId = fingerid;
dragging = true;
//checks if Im pressing the joystick used for moving
}
else if(x > shootingxMesh - (joystick.get_joystickBg().getWidth()) && x < panel.getWidth()
&& y > yMesh - (joystick.get_joystickBg().getHeight()) && y < panel.getHeight()){
shootingPoint.x = x;
shootingPoint.y = y;
//shootingPointerId = pid;
shootingPointerId = fingerid;
shooting=true;
//checks if Im pressing the joystick used for shooting
}
}catch(Exception e){
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_OUTSIDE:
if( fingerid == movePointerId ){ //changed this line
movePointerId = -1;
dragging = false;
}
else if( fingerid == shootingPointerId ){ //changed this line
shootingPointerId = -1;
shooting=false;
}
actionString = "UP";
break;
case MotionEvent.ACTION_MOVE: // this is where my problem is
if( fingerid == movePointerId ) { //changed this line
movingPoint.x = x;
movingPoint.y = y;
} else if( fingerid == shootingPointerId ) { //changed this line
shootingPoint.x = x;
shootingPoint.y = y;
}
actionString = "MOVE";
break;
}
The reason for this is that on some devices de pointer id may change when you release one finger. For example, first finger receives pointer id 1, then you press second finger which receives pointer id 2, and if then you release finger 1, pointer id from finger 2 may become 1. It may sound a bit confusing, but you should avoid the issue with this finger id above.
good luck.
Pointers have two different properties available to identify them:
index: it ranges from 0 to one less than the value returned by getPointerCount(). It is only valid during the processing of the current event.
id: this property uniquely identifies the pointer, and is guaranted to stay the same for the pointer during its whole lifetime.
In your code you are not correctly retrieving the index and id info. Basically you are using the index to identify the pointer across several events, something that is completely wrong, as the index may vary, which is what you are experiencing in your app. In short, you should be using the id to identify the pointer.
As I mentioned, they way you are retrieving index and id is wrong. The correct way to retrieve those properties would be:
int action = event.getAction();
int actionCode = action & MotionEvent.ACTION_MASK;
int index = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
MotionEvent.ACTION_POINTER_INDEX_SHIFT;
int pid = event.getPointerId(index);
You can refer here for more info: MotionEvent | Android Developers
private int movePointerId = -1; and private int shootingPointerId = -1;, shouldn't them have different values? i dont know really but once i had it a problem then i changed the values and it worked.

Categories

Resources