Android Open Source - crystalball Shake Detector






From Project

Back to project page crystalball.

License

The source code is released under:

GNU Lesser General Public License

If you think the Android project crystalball listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.culebracut.crystalball;
//from ww  w  .  j  ava2  s  .  c  o  m
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;

public class ShakeDetector implements SensorEventListener {

  // Minimum acceleration needed to count as a shake movement
    private static final int MIN_SHAKE_ACCELERATION = 5;
    
    // Minimum number of movements to register a shake
    private static final int MIN_MOVEMENTS = 2;
    
    // Maximum time (in milliseconds) for the whole shake to occur
    private static final int MAX_SHAKE_DURATION = 500;
  
    // Arrays to store gravity and linear acceleration values
  private float[] mGravity = { 0.0f, 0.0f, 0.0f };
  private float[] mLinearAcceleration = { 0.0f, 0.0f, 0.0f };
  
  // Indexes for x, y, and z values
  private static final int X = 0;
  private static final int Y = 1;
  private static final int Z = 2;

  // OnShakeListener that will be notified when the shake is detected
  private OnShakeListener mShakeListener;
  
  // Start time for the shake detection
  long startTime = 0;
  
  // Counter for shake movements
  int moveCount = 0;
    
  // Constructor that sets the shake listener
    public ShakeDetector(OnShakeListener shakeListener) {
      mShakeListener = shakeListener;
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
      // This method will be called when the accelerometer detects a change.
      
      // Call a helper method that wraps code from the Android developer site
      setCurrentAcceleration(event);
         
        // Get the max linear acceleration in any direction
        float maxLinearAcceleration = getMaxCurrentLinearAcceleration();
        
        // Check if the acceleration is greater than our minimum threshold
        if (maxLinearAcceleration > MIN_SHAKE_ACCELERATION) {
          long now = System.currentTimeMillis();
          
          // Set the startTime if it was reset to zero
          if (startTime == 0) {
            startTime = now;
          }
          
          long elapsedTime = now - startTime;
          
          // Check if we're still in the shake window we defined
          if (elapsedTime > MAX_SHAKE_DURATION) {
            // Too much time has passed. Start over!
            resetShakeDetection();
          }
          else {
            // Keep track of all the movements
            moveCount++;
            
            // Check if enough movements have been made to qualify as a shake
            if (moveCount > MIN_MOVEMENTS) {
              // It's a shake! Notify the listener.
              mShakeListener.onShake();
              
              // Reset for the next one!
              resetShakeDetection();
            }
          }
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // Intentionally blank
    }
    
    private void setCurrentAcceleration(SensorEvent event) {
         /*
       *  BEGIN SECTION from Android developer site. This code accounts for 
       *  gravity using a high-pass filter
       */
      
      // alpha is calculated as t / (t + dT)
        // with t, the low-pass filter's time-constant
        // and dT, the event delivery rate

        final float alpha = 0.8f;

        // Gravity components of x, y, and z acceleration
        mGravity[X] = alpha * mGravity[X] + (1 - alpha) * event.values[X];
        mGravity[Y] = alpha * mGravity[Y] + (1 - alpha) * event.values[Y];
        mGravity[Z] = alpha * mGravity[Z] + (1 - alpha) * event.values[Z];

        // Linear acceleration along the x, y, and z axes (gravity effects removed)
        mLinearAcceleration[X] = event.values[X] - mGravity[X];
        mLinearAcceleration[Y] = event.values[Y] - mGravity[Y];
        mLinearAcceleration[Z] = event.values[Z] - mGravity[Z];
        
        /*
         *  END SECTION from Android developer site
         */
    }
    
    private float getMaxCurrentLinearAcceleration() {
      // Start by setting the value to the x value
      float maxLinearAcceleration = mLinearAcceleration[X];
      
      // Check if the y value is greater
        if (mLinearAcceleration[Y] > maxLinearAcceleration) {
          maxLinearAcceleration = mLinearAcceleration[Y];
        }
        
        // Check if the z value is greater
        if (mLinearAcceleration[Z] > maxLinearAcceleration) {
          maxLinearAcceleration = mLinearAcceleration[Z];
        }
        
        // Return the greatest value
        return maxLinearAcceleration;
    }
    
    private void resetShakeDetection() {
      startTime = 0;
      moveCount = 0;
    }
    
    /*
     * Definition for OnShakeListener definition. I would normally put this
     * into it's own .java file, but I included it here for quick reference
     * and to make it easier to include this file in our project.
     */
    public interface OnShakeListener {
      public void onShake();
    }
}




Java Source Code List

com.culebracut.crystalball.CrystalBall.java
com.culebracut.crystalball.MainActivity.java
com.culebracut.crystalball.ShakeDetector.java