How to refresh app upon shaking the device?

前端 未结 16 1741
眼角桃花
眼角桃花 2020-11-22 13:42

I need to add a shake feature that will refresh my Android application.

All I find of documentation involves implementing the SensorListener, but Eclips

相关标签:
16条回答
  • 2020-11-22 14:12

    Shaker.java

        import java.util.ArrayList;
        import android.content.Context;
        import android.hardware.Sensor;
        import android.hardware.SensorEvent;
        import android.hardware.SensorEventListener;
        import android.hardware.SensorManager;
    
        public class Shaker implements SensorEventListener{
    
            private static final String SENSOR_SERVICE = Context.SENSOR_SERVICE;
            private SensorManager sensorMgr;
            private Sensor mAccelerometer;
            private boolean accelSupported;
            private long timeInMillis;
            private long threshold;
            private OnShakerTreshold listener;
            ArrayList<Float> valueStack;
    
            public Shaker(Context context, OnShakerTreshold listener, long timeInMillis, long threshold) {
                try {
                    this.timeInMillis = timeInMillis;
                    this.threshold = threshold;
                    this.listener = listener;
                    if (timeInMillis<100){
                        throw new Exception("timeInMillis < 100ms");
                    }
                    valueStack = new ArrayList<Float>((int)(timeInMillis/100));
                    sensorMgr = (SensorManager) context.getSystemService(SENSOR_SERVICE);
                    mAccelerometer = sensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    
                } catch (Exception e){
                    e.printStackTrace();
                }
            }
    
            public void start() {
                try {
                    accelSupported = sensorMgr.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME); 
                    if (!accelSupported) {
                        stop();
                        throw new Exception("Sensor is not supported");
                    }
                } catch (Exception e){
                    e.printStackTrace();
                }
            }
    
            public void stop(){
                try {
                    sensorMgr.unregisterListener(this, mAccelerometer);
                } catch (Exception e){
                    e.printStackTrace();
                }
            }
    
            @Override
            protected void finalize() throws Throwable {
                try {
                    stop();
                } catch (Exception e){
                    e.printStackTrace();
                }
                super.finalize();
            }
    
            long lastUpdate = 0;
            private float last_x;
            private float last_y;
            private float last_z;
    
    public void onSensorChanged(SensorEvent event) {
        try {
            if (event.sensor == mAccelerometer) {
                long curTime = System.currentTimeMillis();
                if ((curTime-lastUpdate)>getNumberOfMeasures()){
    
                    lastUpdate = System.currentTimeMillis();
                    float[] values = event.values;
                    if (valueStack.size()>(int)getNumberOfMeasures())
                        valueStack.remove(0);
                    float x = (int)(values[SensorManager.DATA_X]);
                    float y = (int)(values[SensorManager.DATA_Y]);
                    float z = (int)(values[SensorManager.DATA_Z]);
                    float speed = Math.abs((x+y+z) - (last_x + last_y + last_z));
    
                    valueStack.add(speed);
    
                    String posText = String.format("X:%4.0f Y:%4.0f Z:%4.0f", (x-last_x), (y-last_y), (z-last_z));
    
                    last_x = (x);
                    last_y = (y);
                    last_z = (z);
    
                    float sumOfValues = 0;
                    float avgOfValues = 0;
    
                    for (float f : valueStack){
                            sumOfValues = (sumOfValues+f);
                    }
                    avgOfValues = sumOfValues/(int)getNumberOfMeasures();
    
                    if (avgOfValues>=threshold){
                        listener.onTreshold();
                        valueStack.clear();
                    }
    
                    System.out.println(String.format("M: %+4d A: %5.0f V: %4.0f %s", valueStack.size(),avgOfValues,speed,posText));
    
                }
            }
        } catch (Exception e){
            e.printStackTrace();
        }
    }
    
    
            private long getNumberOfMeasures() {
                return timeInMillis/100;
            }
    
            public void onAccuracyChanged(Sensor sensor, int accuracy) {}
    
            public interface OnShakerTreshold {
                public void onTreshold();
            }
        }
    

    MainActivity.java

    public class MainActivity extends Activity implements OnShakerTreshold{
    
    
        private Shaker s;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            s = new Shaker(getApplicationContext(), this, 5000, 20);
            // 5000 = 5 second of shaking
            // 20 = minimal threshold (very angry shaking :D)
            // beware screen rotation reset counter
        }
    
        @Override
        protected void onResume() {
            s.start();
            super.onResume();
        }
    
        @Override
        protected void onPause() {
            s.stop();
            super.onPause();
        }
    
        public void onTreshold() {
            System.out.println("FIRE LISTENER");
            RingtoneManager.getRingtone(getApplicationContext(), RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)).play();
        }
    
    
    }
    

    Have fun.

    0 讨论(0)
  • 2020-11-22 14:12
    // Need to implement SensorListener
    public class ShakeActivity extends Activity implements SensorListener {
    // For shake motion detection.
    private SensorManager sensorMgr;
    private long lastUpdate = -1;
    private float x, y, z;
    private float last_x, last_y, last_z;
    private static final int SHAKE_THRESHOLD = 800;
    
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // start motion detection
    sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
    boolean accelSupported = sensorMgr.registerListener(this,
        SensorManager.SENSOR_ACCELEROMETER,
        SensorManager.SENSOR_DELAY_GAME);
    
    if (!accelSupported) {
        // on accelerometer on this device
        sensorMgr.unregisterListener(this,
                SensorManager.SENSOR_ACCELEROMETER);
    }
    }
    
    protected void onPause() {
    if (sensorMgr != null) {
        sensorMgr.unregisterListener(this,
                SensorManager.SENSOR_ACCELEROMETER);
        sensorMgr = null;
        }
    super.onPause();
    }
    
    public void onAccuracyChanged(int arg0, int arg1) {
    // TODO Auto-generated method stub
    }
    
    public void onSensorChanged(int sensor, float[] values) {
    if (sensor == SensorManager.SENSOR_ACCELEROMETER) {
        long curTime = System.currentTimeMillis();
        // only allow one update every 100ms.
        if ((curTime - lastUpdate)> 100) {
        long diffTime = (curTime - lastUpdate);
        lastUpdate = curTime;
    
        x = values[SensorManager.DATA_X];
        y = values[SensorManager.DATA_Y];
        z = values[SensorManager.DATA_Z];
    
        float speed = Math.abs(x+y+z - last_x - last_y - last_z)
                              / diffTime * 10000;
        if (speed > SHAKE_THRESHOLD) {
            // yes, this is a shake action! Do something about it!
        }
        last_x = x;
        last_y = y;
        last_z = z;
        }
    }
    }
    }
    
    0 讨论(0)
  • 2020-11-22 14:13

    Here is my code for shake gesture detection:

    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 = 200;
    
      /** Maximum allowed time for shake gesture. */
      private static final int MAX_TOTAL_DURATION_OF_SHAKE = 400;
    
      /** 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 < MAX_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) {
      }
    
    }
    

    Add this in your activity:

      private SensorManager mSensorManager;
    
      private ShakeEventListener mSensorListener;
    

    ...

    in onCreate() add:

        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        mSensorListener = new ShakeEventListener();   
    
        mSensorListener.setOnShakeListener(new ShakeEventListener.OnShakeListener() {
    
          public void onShake() {
            Toast.makeText(KPBActivityImpl.this, "Shake!", Toast.LENGTH_SHORT).show();
          }
        });
    

    and:

    @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();
      }
    
    0 讨论(0)
  • 2020-11-22 14:15

    Here is another code for this:

    import java.util.List;
    import java.util.Timer;
    import java.util.TimerTask;
    
    import android.content.Context;
    import android.hardware.Sensor;
    import android.hardware.SensorEvent;
    import android.hardware.SensorEventListener;
    import android.hardware.SensorManager;
    import android.os.Handler;
    
       public class AccelerometerListener implements SensorEventListener {
    
            private SensorManager sensorManager;
            private List<Sensor> sensors;
            private Sensor sensor;
            private long lastUpdate = -1;
            private long currentTime = -1;
            private Main parent;
            private Timer timer;
            private int shakes;
            private static final Handler mHandler = new Handler();
    
            private float last_x, last_y, last_z;
            private float current_x, current_y, current_z, currenForce;
            private static final int FORCE_THRESHOLD = 500;
            private final int DATA_X = SensorManager.DATA_X;
            private final int DATA_Y = SensorManager.DATA_Y;
            private final int DATA_Z = SensorManager.DATA_Z;
    
            public AccelerometerListener(Main parent) {
                SensorManager sensorService = (SensorManager) parent
                        .getSystemService(Context.SENSOR_SERVICE);
    
                this.sensorManager = sensorService;
                if (sensorService == null)
                    return;
    
                this.sensors = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
                if (sensors.size() > 0) {
                    sensor = sensors.get(0);
                }
    
                this.parent = parent;
            }
    
            public void start() {
                if (sensor == null)
                    return;
    
                sensorManager.registerListener(this, sensor,
                        SensorManager.SENSOR_DELAY_GAME);
            }
    
            public void stop() {
                if (sensorManager == null)
                    return;
    
                sensorManager.unregisterListener(this);
            }
    
            public void onAccuracyChanged(Sensor s, int valu) {
    
            }
    
            public void onSensorChanged(SensorEvent event) {
    
                if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER)
                    return;
    
                currentTime = System.currentTimeMillis();
    
                if ((currentTime - lastUpdate) > 50) {
                    long diffTime = (currentTime - lastUpdate);
                    lastUpdate = currentTime;
    
                    current_x = event.values[DATA_X];
                    current_y = event.values[DATA_Y];
                    current_z = event.values[DATA_Z];
    
                    currenForce = Math.abs(current_x + current_y + current_z - last_x
                            - last_y - last_z)
                            / diffTime * 10000;
    
                    if (currenForce > FORCE_THRESHOLD) {
                        shakeDetected();
                    }
                    last_x = current_x;
                    last_y = current_y;
                    last_z = current_z;
    
                }
            }
    
            private void shakeDetected() {
                shakes++;
    
                if (shakes == 1) {
                    if (timer != null) {
                        timer.cancel();
                    }
    
                    timer = new Timer();
                    timer.schedule(new TimerTask() {
    
                        @Override
                        public void run() {
                            if (shakes > 3) {
                                mHandler.post(new Runnable() {
    
                                    public void run() {
                                        // shake
                                    }
                                });
                            }
    
                            shakes = 0;
                        }
                    }, 500);
                }
            }
        }
    
    0 讨论(0)
  • 2020-11-22 14:17

    I have written a small example for detecting vertical and horizontal shakes and showing a Toast.

    public class Accelerometerka2Activity extends Activity implements SensorEventListener { 
        private float mLastX, mLastY, mLastZ;
        private boolean mInitialized;
        private SensorManager mSensorManager;
        private Sensor mAccelerometer;
        private final float NOISE = (float) 8.0;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            mInitialized = false;
            mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
            mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
            mSensorManager.registerListener(this, mAccelerometer , SensorManager.SENSOR_DELAY_NORMAL);
        }
    
        protected void onResume() {
            super.onResume();
            mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
        }
    
        protected void onPause() {
            super.onPause();
            mSensorManager.unregisterListener(this);
        }
    
    
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
            // can be safely ignored for this demo
        }
    
    
        public void onSensorChanged(SensorEvent event) {
            float x = event.values[0];
            float y = event.values[1];
            float z = event.values[2];
            if (!mInitialized) {
                mLastX = x;
                mLastY = y;
                mLastZ = z;
                mInitialized = true;
            } else {
                float deltaX = Math.abs(mLastX - x);
                float deltaY = Math.abs(mLastY - y);
                float deltaZ = Math.abs(mLastZ - z);
                if (deltaX < NOISE) deltaX = (float)0.0;
                if (deltaY < NOISE) deltaY = (float)0.0;
                if (deltaZ < NOISE) deltaZ = (float)0.0;
                mLastX = x;
                mLastY = y;
                mLastZ = z;
                if (deltaX > deltaY) {
                    Toast.makeText(getBaseContext(), "Horizental", Toast.LENGTH_SHORT).show();
                } else if (deltaY > deltaX) {
                    Toast.makeText(getBaseContext(), "Vertical", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-22 14:18

    You might want to try open source tinybus. With it shake detection is as easy as this.

    public class MainActivity extends Activity {
    
        private Bus mBus;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            ...
    
            // Create a bus and attach it to activity
            mBus = TinyBus.from(this).wire(new ShakeEventWire());
        }
    
        @Subscribe
        public void onShakeEvent(ShakeEvent event) {
            Toast.makeText(this, "Device has been shaken", 
                    Toast.LENGTH_SHORT).show();
        }
    
        @Override
        protected void onStart() {
            super.onStart();
            mBus.register(this);
        }
    
        @Override
        protected void onStop() {
            mBus.unregister(this);
            super.onStop();
        }
    }
    

    It uses seismic for shake detection.

    0 讨论(0)
提交回复
热议问题