para - Toque en la pantalla 5 veces en 3 segundos en Android
doble toque para encender pantalla apk (4)
Estoy desarrollando un kiosco y ahora en el lado de administración. Para ir al administrador, el usuario debe tocar la pantalla 5 veces en solo 3 segundos , de lo contrario, no ocurrirá nada. ¿Alguien puede ayudarme con esta preocupación? ¡Gracias de antemano!
Mi solución es similar a la de Andres''s . La cuenta regresiva comienza cuando levanta el dedo por primera vez, es decir, cuando considero que el grifo está terminado. Esto es similar a los clics, se produce un clic al soltar el botón del mouse. Después de 3 segundos desde el primer levantamiento, el contador se reinicia. El enfoque de Andrés, en el otro lado, usa la lógica basada en colocar el dedo hacia abajo en la pantalla. También utiliza un hilo adicional.
Mi lógica es una de las muchas posibles. Otro enfoque razonable sería detectar 5 toques consecutivos dentro de 3 segundos en un flujo de toques. Considerar:
tap1 , 2000ms, tap2 , 500ms, tap3 , 550ms, tap4 , 10ms, tap5 , 10ms, tap6 .
La segunda a la sexta pulsación abarca un conjunto de cinco pulsaciones en menos de 3 segundos; en mi enfoque esto no sería detectado. Para detectar esto, puede usar una cola FIFO de tamaño fijo 5 y recordar las últimas 5 marcas de tiempo: esta secuencia está aumentando. Cuando recibe un nuevo toque, verifica si 1) se produjeron al menos 5 toques, y 2) la marca de tiempo más antigua no tiene más de 3 segundos.
De todos modos, volviendo a la primera lógica, coloque este código en una 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);
}
}
Nota: probablemente también desee cierta retención de estado en los cambios de configuración. Como diría un matemático, lo dejo como un ejercicio para el lector
Por favor, lea los comentarios en el código, es bastante sencillo.
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;
}
}
onTouchEvent()
método Activity onTouchEvent()
para recibir los eventos táctiles de la pantalla. Cada vez que el usuario toca la pantalla, incrementa una variable y pospone un Runnable en 3 segundos si es la primera vez que toca, si pasan 3 segundos, los eventos táctiles se borrarán y no sucederá nada. A Thread comprueba que el número de eventos táctiles sea 5 o más, si ocurrieron antes de los 3 segundos, la variable no se borrará y la if(touchEvent >= 5)
es verdadera. ¡No lo he probado! Pero es completamente asíncrono :)
// 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 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){
}
}
}