Tap on screen 5 Times in 3 seconds in android Tap on screen 5 Times in 3 seconds in android android android

Tap on screen 5 Times in 3 seconds in android


Please read the comments in the code, it is quite straightforward

import android.app.Activity;import android.os.Bundle;import android.view.MotionEvent;public class MainActivity extends Activity {private int count = 0;private long startMillis=0;//detect any touch event in the screen (instead of an specific view)@Overridepublic boolean onTouchEvent(MotionEvent event) {      int eventaction = event.getAction();     if (eventaction == MotionEvent.ACTION_UP) {     //get system current milliseconds     long time= System.currentTimeMillis();     //if it is the first time, or if it has been more than 3 seconds since the first tap ( so it is like a new try), we reset everything      if (startMillis==0 || (time-startMillis> 3000) ) {         startMillis=time;         count=1;     }     //it is not the first, and it has been  less than 3 seconds since the first     else{ //  time-startMillis< 3000            count++;     }     if (count==5) {        //do whatever you need     }     return true;        }    return false;  }}


My solution is similar to Andres's. The countdown starts when you lift the finger for the first time, that is, when I consider the tap to be finished. This is similar to clicks, a click occurs when you release the mouse button. After 3 seconds from the first lift, the counter is reset. Andres's approch, on the other side, uses logic based on placing the finger down onto the screen. It also uses an additional thread.

My logic is one of the many possible ones. Another reasonable approach would be to detect 5 consecutive taps within 3 seconds in a stream of taps. Consider:

tap1, 2000ms, tap2, 500ms, tap3, 550ms, tap4, 10ms, tap5, 10ms, tap6.

The second through the sixth tap encompasses a set of five taps in less than 3 seconds; in my approach this would not be detected. To detect this you can use a FIFO queue of fixed size 5 and remember the last 5 timestamps: this sequence is increasing. When you receive a new tap, you check whether 1) there are at least 5 taps occurred, and 2) the oldest timestamp is no older then 3 seconds old.

Anyway, back to the first logic, place this code in an Activity:

private int mCounter = 0;private Handler mHandler = new Handler();private Runnable mResetCounter = new Runnable() {    @Override    public void run() {        mCounter = 0;    }};@Overridepublic boolean onTouchEvent(MotionEvent event) {    switch(MotionEventCompat.getActionMasked(event)) {        case MotionEvent.ACTION_UP:        case MotionEvent.ACTION_CANCEL:            if (mCounter == 0)                mHandler.postDelayed(mResetCounter, 3000);            mCounter++;            if (mCounter == 5){                mHandler.removeCallbacks(mResetCounter);                mCounter = 0;                Toast.makeText(this, "Five taps in three seconds", Toast.LENGTH_SHORT).show();            }            return false;        default :             return super.onTouchEvent(event);    }}

Note: you probably want some state retention on configuration changes too. As a mathematician would say, I let that as an exercise to the reader


Override your Activity onTouchEvent() method to receive the touch events from the screen. Every time the user taps the screen increment a variable and postpone a Runnable in 3 seconds if it's the first time you touch, if 3 seconds passes the touch events will be cleared and nothing happens. A Thread checks for the touch events number to be 5 or more, if they happened before the 3 seconds the variable is not cleared and the if(touchEvent >= 5) condition is true. I haven't tested it! But it's completely asynchronous :)

// Touch events on screen@Overridepublic boolean onTouchEvent(MotionEvent event) {        // User pressed the screen        if(event.getAction() == MotionEvent.ACTION_DOWN){          if(touchEvent == 0) myView.post(mRunnable, 3000);  // Execute a Runnable in 3 seconds          ++touchEvent;        }        return false;}Runnable mRunnable = new Runnable(){        @Override        public void run() {           touchEvent = 0; // 3 seconds passed, clear touch events        }}Thread mThread = new Thread(new Runnable(){   @Override   public void run(){      if(touchEvent >= 5){         // Touched 5 times in 3 seconds or less, CARE this is not UI Thread!      }   }});mThread.start();