Touch events not triggering on Android

ontouchevent android
touchmove not working
android-activity ontouchevent
touch click event
touchstart touchend
touchmove event

I have an activity where user can see the "about" about the simple app I'm trying to develope. I'm using "Android About Page" to show it but plus I'd like to detect the number of taps on the screen so that a Toast message can appear when the right number of taps are detected...sort of easter egg :) The problem I'm facing is that touch events are not triggered... this is the code I'm using:

public class About extends AppCompatActivity {
   @Override
   public void onTouchEvent(MotionEvent event) {
      Log.i("LOG_RESPONSE", "Screen touched!");
   }  

   @Override
   protected void onCreate(Bundle savedInstanceState) {
      //// other code
   }
}

This is my XML:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 
   xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   android:id="@+id/layer"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context=".About">

   <View
       android:id="@+id/myView"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       app:layout_constraintBottom_toBottomOf="parent"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

No errors, it just does nothing.

EDIT as suggested using onTouch():

public class About extends AppCompatActivity {

   View test;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);

       test = (View)findViewById(R.id.myView);
       test.setOnTouchListener(new View.OnTouchListener() {
          @Override
          public boolean onTouch(View v, MotionEvent event) {
             Log.i("LOG_RESPONSE", "Screen touched!");
             return false;
          }
       });
       //// other code 
   }
}

This way the app crashes:

Caused by: java.lang.NullPointerException

EDIT 2 - It does not crash anymore but no touch is recognized:

public class About extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_about);
        View test = findViewById(R.id.layer);
        Log.i("LOG_RESPONSE", test.toString());

    test.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            Log.i("LOG_RESPONSE", "Screen touched!");
            return false;
        }
    });
}

Since you want to count every tap on the entire screen and not just a particular view, you should set a touch event listener on the activity layout, in your case it's called "@+id/layer"

so this is what you want:

findViewById(R.id.layer).setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            counter++;
            if(counter==8)
                Toast.makeText(About.this, "Surprise!!", Toast.LENGTH_SHORT).show();
                Log.i("LOG_RESPONSE", "Screen touched!");
            return false;
        }
    });

In the example i used 8 as the target number for the event, but of course you can declare it above and use it.

Edit: As far as the java.lang.NullPointerException , the reason is you declared the view as a class member object, the problem is you can't instantiate it, because it takes a context as a parameter and since the onCreate method hasn't run yet, well, there is no context, so there's no way you can instantiate it therefore it's better to declare it in the on create method.

So, this your problem :

public class About extends AppCompatActivity {
    View test;//remove this
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_about);
        test =(View)findViewById(R.id.myView);
        //// other code
    }
}

and this is the solution

public class About extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_about);
        View test =(View)findViewById(R.id.myView);//Declare it and initialize it here
        //// other code
    }
}

Android - OnTouch event not firing fix., Attempting to use the OnTouchListener interface, the method it implements is not what fires, it Duration: 1:53 Posted: Sep 25, 2012 Therefor the lower priority OnClickListener is not called. Each successive touch doesn't change the focus so these events trickle down to the OnClickListener. Buttons (and other such components) don't receive focus from a touch event, that's why the OnClickListener is called every time. Basically, you have three choices:

Please see following answer

https://stackoverflow.com/a/5002073/9640177

onTouch() is used by users of the View to get touch events while onTouchEvent() is used by derived classes of the View to get touch events.

To achieve your purpose one possible solution would be to use a transparent view that fills entire screen and define onTouchListner on that view.

Add following view as the last child of rootView

 <View android:id = "@+id/countTouch"
          android:layout_height = "match_parent"
          android:layout_weight = "match_parent"
          android:background = "#00000000">

In your onCreate() method set onTouchListener as follows

   findViewById(R.id.countTouch).setOnTouchListener(new OnTouchListnere{
         public boolean onTouch(MotionEvent e){
                if(e.getAction()==MotionEvent.ACTION_DOWN){
                        counter++; // increment your global counter variable
                        //Log screen touched
                 }
                return false;
         }
     };

How to bind 'touchstart' and 'click' events but not respond to both , If an application does not want mouse events fired on a specific touch target element, the Here a touchstart event is triggered After triggering an event. ViewParent.requestDisallowInterceptTouchEvent(boolean) - Call this upon a parent View to indicate that it should not intercept touch events with onInterceptTouchEvent(MotionEvent). Touch Mode When a user is navigating a user interface with directional keys or a trackball, it is necessary to give focus to actionable items (like buttons) so the user can see what will accept input.

This is answer to the updated question -- in response to the remaining issue after implementation of answer to the previous part

You need to change wrap_content to match_parent. Your view has nothing in it so wrap_content will set its height and width to 0. So when you are touching the screen you are touching the parent ConstraintLayout and not your View.

<View
   android:id="@+id/myView"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   app:layout_constraintBottom_toBottomOf="parent"
   app:layout_constraintEnd_toEndOf="parent"
   app:layout_constraintStart_toStartOf="parent"
   app:layout_constraintTop_toTopOf="parent" />

Hope this helps someone ending up here.

Touchmove event not working in Mobile Browsers · Issue #4632 , Touchmove events are not working as expected in SPFx webpart. Issue is probably PS: I am aware of touchmove doesn't fire as expected in Android Chrome. Probably the newer package handled touch events differently. Consequently, if an application does not want mouse events fired on a specific touch target element, the element's touch event handlers should call preventDefault() and no additional mouse events will be dispatched. Here is a code snippet of the touchmove event handler calling preventDefault().

Manage touch events in a ViewGroup, If you drag your finger across a child view horizontally, the child view should no longer get touch events, and MyViewGroup should handle  I have tested on Chromium 60 (Ubuntu, and simulated device), Chrome 59 (Android), Firefox 54 (Ubuntu), Firefox 55 (Android), and Edge 40 (Windows 10). It works there, and dblclick only appear once. These are the events triggered on every browser shown using the link above (doing doble click or tap once): Chromium 60 Ubuntu Leaflet 1.2.0+master

Touch events not working? (both platforms, latest victory-native , I too have tried the above one, it doesn't work for Android. Adding to above code snippet, onPress , onPressOut do not fire when I use container  What I’m trying to say is that a touch is not as accurate as a mouse. Android and iPhone touch events. Android and iPhone versions of WebKit have some touch events in common: touchstart – triggered when a touch is initiated. Mouse equivalent – mouseDown; touchmove – triggered when a touch moves. Mouse equivalent – mouseMove

Touch events, The touch events interfaces are relatively low-level APIs that can be used prevents the corresponding mouse events from firing, it's common to call with both fingers; Android will allow zooming but not panning; Opera and  you override the onTouchEvent () method. The MotionEvent class contains the touch related information, e.g., the number of pointers, the X/Y coordinates and size and pressure of each pointer. This method returns true if the touch event has been handled by the view. Android tries to find the deepest view which returns true to handles the touch event.

Comments
  • Thank you. Unfortunately it crashes. "java.lang.NullPointerException"
  • it's because of the way you decalred your View object
  • It is not crashing anymore but no touch is detected. Please see EDIT 2 in main thread.