2017-04-18 4 views
0

J'utilise un accéléromètre pour la détection de secousses, mais je veux que si un utilisateur secoue ses appareils pendant 8 secondes, la méthode résultante sera déclenchée. Avec mon code actuel un peut capable de détecter le tremblement, mais je veux une minuterie 8sec aussi. Mon code actuel estDetect Shake for 8 Sec

public class AccelerometerManager { 
    private static Context aContext=null; 

    /** Accuracy configuration */ 
    private static float threshold = 15.0f; 
    private static int interval  = 200; 

    private static Sensor sensor; 
    private static SensorManager sensorManager; 
    // you could use an OrientationListener array instead 
    // if you plans to use more than one listener 
    private static AccelerometerListener listener; 

    /** indicates whether or not Accelerometer Sensor is supported */ 
    private static Boolean supported; 
    /** indicates whether or not Accelerometer Sensor is running */ 
    private static boolean running = false; 

    /** 
    * Returns true if the manager is listening to orientation changes 
    */ 
    public static boolean isListening() { 
     return running; 
    } 

    /** 
    * Unregisters listeners 
    */ 
    public static void stopListening() { 
     running = false; 
     try { 
      if (sensorManager != null && sensorEventListener != null) { 
       sensorManager.unregisterListener(sensorEventListener); 
      } 
     } catch (Exception e) {} 
    } 

    /** 
    * Returns true if at least one Accelerometer sensor is available 
    */ 
    public static boolean isSupported(Context context) { 
     aContext = context; 
     if (supported == null) { 
      if (aContext != null) { 


       sensorManager = (SensorManager) aContext. 
         getSystemService(Context.SENSOR_SERVICE); 

       // Get all sensors in device 
       List<Sensor> sensors = sensorManager.getSensorList(
         Sensor.TYPE_ACCELEROMETER); 

       supported = new Boolean(sensors.size() > 0); 



      } else { 
       supported = Boolean.FALSE; 
      } 
     } 
     return supported; 
    } 

    /** 
    * Configure the listener for shaking 
    * @param threshold 
    *    minimum acceleration variation for considering shaking 
    * @param interval 
    *    minimum interval between to shake events 
    */ 
    public static void configure(int threshold, int interval) { 
     AccelerometerManager.threshold = threshold; 
     AccelerometerManager.interval = interval; 
    } 

    /** 
    * Registers a listener and start listening 
    * @param accelerometerListener 
    *    callback for accelerometer events 
    */ 
    public static void startListening(AccelerometerListener accelerometerListener) 
    { 

     sensorManager = (SensorManager) aContext. 
       getSystemService(Context.SENSOR_SERVICE); 

     // Take all sensors in device 
     List<Sensor> sensors = sensorManager.getSensorList(
       Sensor.TYPE_ACCELEROMETER); 

     if (sensors.size() > 0) { 

      sensor = sensors.get(0); 

      // Register Accelerometer Listener 
      running = sensorManager.registerListener(
        sensorEventListener, sensor, 
        SensorManager.SENSOR_DELAY_GAME); 

      listener = accelerometerListener; 
     } 


    } 

    /** 
    * Configures threshold and interval 
    * And registers a listener and start listening 
    * @param accelerometerListener 
    *    callback for accelerometer events 
    * @param threshold 
    *    minimum acceleration variation for considering shaking 
    * @param interval 
    *    minimum interval between to shake events 
    */ 
    public static void startListening(
      AccelerometerListener accelerometerListener, 
      int threshold, int interval) { 
     configure(threshold, interval); 
     startListening(accelerometerListener); 
    } 

    /** 
    * The listener that listen to events from the accelerometer listener 
    */ 
    private static SensorEventListener sensorEventListener = 
      new SensorEventListener() { 

       private long now = 0; 
       private long timeDiff = 0; 
       private long lastUpdate = 0; 
       private long lastShake = 0; 

       private float x = 0; 
       private float y = 0; 
       private float z = 0; 
       private float lastX = 0; 
       private float lastY = 0; 
       private float lastZ = 0; 
       private float force = 0; 

       public void onAccuracyChanged(Sensor sensor, int accuracy) {} 

       public void onSensorChanged(SensorEvent event) { 
        // use the event timestamp as reference 
        // so the manager precision won't depends 
        // on the AccelerometerListener implementation 
        // processing time 
        now = event.timestamp; 

        x = event.values[0]; 
        y = event.values[1]; 
        z = event.values[2]; 

        // if not interesting in shake events 
        // just remove the whole if then else block 
        if (lastUpdate == 0) { 
         lastUpdate = now; 
         lastShake = now; 
         lastX = x; 
         lastY = y; 
         lastZ = z; 
         Toast.makeText(aContext,"No Motion detected", 
           Toast.LENGTH_SHORT).show(); 

        } else { 
         timeDiff = now - lastUpdate; 

         if (timeDiff > 0) { 

        /*force = Math.abs(x + y + z - lastX - lastY - lastZ) 
           /timeDiff;*/ 
          force = Math.abs(x + y + z - lastX - lastY - lastZ); 

          if (Float.compare(force, threshold) >0) { 

           if (now - lastShake >= 8000000000l) { 

            // trigger shake event 
            listener.onShake(force); 
           } 
           else 
           { 
            Toast.makeText(aContext,"No Motion detected", 
              Toast.LENGTH_SHORT).show(); 

           } 
           lastShake = now; 
          } 
          lastX = x; 
          lastY = y; 
          lastZ = z; 
          lastUpdate = now; 
         } 
         else 
         { 
          Toast.makeText(aContext,"No Motion detected", Toast.LENGTH_SHORT).show(); 

         } 
        } 
        // trigger change event 
        listener.onAccelerationChanged(x, y, z); 
       } 

      }; 

} 
+1

Quel est le problème dans le code ci-dessus? Est-ce que l'événement Shake est détecté ou non? –

+0

tremblement est détecté mais je veux un secousse continue pendant 8 sec – Ritesh

+0

Signifie, voulez-vous la détection après que l'utilisateur continue à secouer le téléphone pendant 8 secondes? –

Répondre

2

Essayez ci-dessous le code de détection pour secouer poursuit en 8 secondes.

import android.hardware.Sensor; 
import android.hardware.SensorEvent; 
import android.hardware.SensorEventListener; 
import android.hardware.SensorManager; 


/** 
* Listener that detects shake gesture. 
*/ 
public class ShakeEventListener implements SensorEventListener { 


    /** Minimum movement force to consider. */ 
    private static final int MIN_FORCE = 10; 

    /** 
    * Minimum times in a shake gesture that the direction of movement needs to 
    * change. 
    */ 
    private static final int MIN_DIRECTION_CHANGE = 3; 

    /** Maximum pause between movements. */ 
    private static final int MAX_PAUSE_BETHWEEN_DIRECTION_CHANGE = 1000; 

    /** Minimum allowed time for shake gesture. */ 
    private static final int MIN_TOTAL_DURATION_OF_SHAKE = 8000; // 8 seconds 

    /** Time when the gesture started. */ 
    private long mFirstDirectionChangeTime = 0; 

    /** Time when the last movement started. */ 
    private long mLastDirectionChangeTime; 

    /** How many movements are considered so far. */ 
    private int mDirectionChangeCount = 0; 

    /** The last x position. */ 
    private float lastX = 0; 

    /** The last y position. */ 
    private float lastY = 0; 

    /** The last z position. */ 
    private float lastZ = 0; 

    /** OnShakeListener that is called when shake is detected. */ 
    private OnShakeListener mShakeListener; 

    /** 
    * Interface for shake gesture. 
    */ 
    public interface OnShakeListener { 

    /** 
    * Called when shake gesture is detected. 
    */ 
    void onShake(); 
    } 

    public void setOnShakeListener(OnShakeListener listener) { 
    mShakeListener = listener; 
    } 

    @Override 
    public void onSensorChanged(SensorEvent se) { 
    // get sensor data 
    float x = se.values[SensorManager.DATA_X]; 
    float y = se.values[SensorManager.DATA_Y]; 
    float z = se.values[SensorManager.DATA_Z]; 

    // calculate movement 
    float totalMovement = Math.abs(x + y + z - lastX - lastY - lastZ); 

    if (totalMovement > MIN_FORCE) { 

     // get time 
     long now = System.currentTimeMillis(); 

     // store first movement time 
     if (mFirstDirectionChangeTime == 0) { 
     mFirstDirectionChangeTime = now; 
     mLastDirectionChangeTime = now; 
     } 

     // check if the last movement was not long ago 
     long lastChangeWasAgo = now - mLastDirectionChangeTime; 
     if (lastChangeWasAgo < MAX_PAUSE_BETHWEEN_DIRECTION_CHANGE) { 

     // store movement data 
     mLastDirectionChangeTime = now; 
     mDirectionChangeCount++; 

     // store last sensor data 
     lastX = x; 
     lastY = y; 
     lastZ = z; 

     // check how many movements are so far 
     if (mDirectionChangeCount >= MIN_DIRECTION_CHANGE) { 

      // check total duration 
      long totalDuration = now - mFirstDirectionChangeTime; 
      if (totalDuration >= MIN_TOTAL_DURATION_OF_SHAKE) { 
      mShakeListener.onShake(); 
      resetShakeParameters(); 
      } 
     } 

     } else { 
     resetShakeParameters(); 
     } 
    } 
    } 

    /** 
    * Resets the shake parameters to their default values. 
    */ 
    private void resetShakeParameters() { 
    mFirstDirectionChangeTime = 0; 
    mDirectionChangeCount = 0; 
    mLastDirectionChangeTime = 0; 
    lastX = 0; 
    lastY = 0; 
    lastZ = 0; 
    } 

    @Override 
    public void onAccuracyChanged(Sensor sensor, int accuracy) { 
    } 

} 

AJOUTZ code dans votre activité:

private SensorManager mSensorManager; 

    private ShakeEventListener mSensorListener; 


    mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 
    mSensorListener = new ShakeEventListener(); 

    mSensorListener.setOnShakeListener(new ShakeEventListener.OnShakeListener() { 

     public void onShake() { 
     Toast.makeText(this, "Shake detected!", Toast.LENGTH_SHORT).show(); 
     } 
    }); 

Inscrivez-vous auditeur de bougé dans onResume méthode désinscriptions dans la méthode comme ci-dessous.

@Override 
    protected void onResume() { 
    super.onResume(); 
    mSensorManager.registerListener(mSensorListener, 
     mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), 
     SensorManager.SENSOR_DELAY_UI); 
    } 

    @Override 
    protected void onPause() { 
    mSensorManager.unregisterListener(mSensorListener); 
    super.onPause(); 
    }