Нажмите на экран 5 раз за 3 секунды в Android

Я разрабатываю киоск и теперь на стороне администратора. Для того, чтобы перейти к администратору, пользователю нужно нажать на экран 5 раз всего за 3 секунды, иначе ничего не произойдет. Может ли кто-нибудь помочь мне с этим беспокойством? Заранее спасибо!

4 ответа

Решение

Пожалуйста, прочитайте комментарии в коде, это довольно просто

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)

@Override
public 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;
  }

}

Мое решение похоже на решение Андреса. Обратный отсчет начинается, когда вы впервые поднимаете палец, то есть когда я считаю, что нажатие закончено. Это похоже на щелчки, щелчок происходит, когда вы отпустите кнопку мыши. Через 3 секунды после первого подъема счетчик сбрасывается. Подход Андреса, с другой стороны, использует логику, основанную на помещении пальца на экран. Также используется дополнительная нить.

Моя логика одна из многих возможных. Другим разумным подходом было бы обнаружение 5 последовательных нажатий в течение 3 секунд в потоке нажатий. Рассматривать:

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

Отвод со второго по шестой охватывает набор из пяти отводов менее чем за 3 секунды; в моем подходе это не будет обнаружено. Чтобы обнаружить это, вы можете использовать очередь FIFO фиксированного размера 5 и запомнить последние 5 временных меток: эта последовательность увеличивается. При получении нового касания вы проверяете, 1) произошло ли как минимум 5 нажатий, и 2) самая старая отметка времени не старше 3 секунд.

В любом случае, вернемся к первой логике, поместите этот код в Activity:

private int mCounter = 0;
private Handler mHandler = new Handler();

private Runnable mResetCounter = new Runnable() {
    @Override
    public void run() {
        mCounter = 0;
    }
};

@Override
public 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);
    }
}

Примечание: вы, вероятно, хотите сохранить состояние при изменении конфигурации. Как сказал бы математик, я позволил читателю это сделать

Переопределите вашу активность onTouchEvent() способ получения сенсорных событий с экрана. Каждый раз, когда пользователь нажимает на экран, увеличивают переменную и откладывают Runnable на 3 секунды, если вы касаетесь в первый раз, если проходит 3 секунды, сенсорные события будут очищены и ничего не произойдет. Поток проверяет, чтобы число событий касания было 5 или более, если они произошли до 3 секунд, переменная не очищается и if(touchEvent >= 5) условие верно. Я не проверял это! Но это полностью асинхронно:)

// Touch events on screen
@Override
public 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();

Если вы хотите обнаружить прикосновение к виду в КОТЛИН

private var count = 0
private var startMillis: Long = 0
        
textView.setOnTouchListener { v, event ->
        if (event.action == MotionEvent.ACTION_UP) {
            val currentTime = System.currentTimeMillis()
            if (startMillis == 0L || currentTime - startMillis > 3000) {
                startMillis = currentTime
                count = 1
            } else {
                count++
            }
            if (count == 4) {
                
            }

            logd("count -- $count")
        }
        false
    }

В Java: /questions/1534874/nazhmite-na-ekran-5-raz-za-3-sekundyi-v-android/1534890#1534890

private int touchSequenceCount = 0;
private Handler handlerTouchSequenceDetection;
private Runnable runnableTouchSequenceDetection;

public void setupTouchSequenceDetection(final View view){

    try {   

        view.setOnTouchListener(new View.OnTouchListener() {               
            public boolean onTouch(View v, MotionEvent event) {             

                int action = event.getAction();

                switch (action) {

                    case MotionEvent.ACTION_DOWN:

                        Log.d("setupTouchSequenceDetection", "touchCount: " + (touchSequenceCount+1));

                        if(touchSequenceCount == 0){

                            handlerTouchSequenceDetection.postDelayed(runnableTouchSequenceDetection, 2000);    

                        }else{

                            if(touchSequenceCount == 2){        

                                new AlertDialog.Builder(Activity_CheckIn_SelectLanguage.this)
                                .setMessage("warning message here")
                                .setCancelable(true)
                                .setPositiveButton("yes", new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int id) {

                                        resetTouchSequenceDetection(true);
                                    }
                                })
                                .setNegativeButton("no", new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int id) {

                                        resetTouchSequenceDetection(true);
                                    }
                                }).setOnCancelListener(new DialogInterface.OnCancelListener() {

                                    @Override
                                    public void onCancel(DialogInterface dialog) {

                                        resetTouchSequenceDetection(true);
                                    }
                                })
                                .show();
                            }

                        }

                        touchSequenceCount = touchSequenceCount + 1;

                    break;
                } 

                return false;
            }
        });


        handlerTouchSequenceDetection = new Handler(); 

        runnableTouchSequenceDetection = new Runnable() { 
             public void run() { 

                 Log.d("setupTouchSequenceDetection", "reset touchCount: " + (touchSequenceCount+1));

                 resetTouchSequenceDetection(false);
             } 
        };

    }
    catch(Exception ex){

        if(ex != null){

        }
    }
}

private void resetTouchSequenceDetection(boolean removeRunnable){

    try{

        if(removeRunnable){
            handlerTouchSequenceDetection.removeCallbacks(runnableTouchSequenceDetection);
        }

        touchSequenceCount = 0; 

    }
    catch(Exception ex){

        if(ex != null){

        }
    }
}
Другие вопросы по тегам