How to refresh app upon shaking the device?

前端 未结 16 1740
眼角桃花
眼角桃花 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:01
    package anywheresoftware.b4a.student;
    
    import android.hardware.Sensor;
    import android.hardware.SensorEvent;
    import android.hardware.SensorEventListener;
    import android.hardware.SensorManager;
    import android.util.FloatMath;
    
    public class ShakeEventListener implements SensorEventListener {
    
        /*
         * The gForce that is necessary to register as shake.
         * Must be greater than 1G (one earth gravity unit).
         * You can install "G-Force", by Blake La Pierre
         * from the Google Play Store and run it to see how
         *  many G's it takes to register a shake
         */
        private static final float SHAKE_THRESHOLD_GRAVITY = 2.7F;
        private static int SHAKE_SLOP_TIME_MS = 500;
        private static final int SHAKE_COUNT_RESET_TIME_MS = 1000;
    
        private OnShakeListener mListener;
        private long mShakeTimestamp;
        private int mShakeCount;
    
        public void setOnShakeListener(OnShakeListener listener) {
            this.mListener = listener;
        }
    
        public interface OnShakeListener {
            public void onShake(int count);
        }
    
        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
            // ignore
        }
    
        @Override
        public void onSensorChanged(SensorEvent event) {
    
            if (mListener != null) {
                float x = event.values[0];
                float y = event.values[1];
                float z = event.values[2];
    
                float gX = x / SensorManager.GRAVITY_EARTH;
                float gY = y / SensorManager.GRAVITY_EARTH;
                float gZ = z / SensorManager.GRAVITY_EARTH;
    
                // gForce will be close to 1 when there is no movement.
                float gForce = FloatMath.sqrt(gX * gX + gY * gY + gZ * gZ);
    
                if (gForce > SHAKE_THRESHOLD_GRAVITY) {
                    final long now = System.currentTimeMillis();
                    // ignore shake events too close to each other (500ms)
                    if (mShakeTimestamp + getSHAKE_SLOP_TIME_MS() > now) {
                        return;
                    }
    
                    // reset the shake count after 3 seconds of no shakes
                    if (mShakeTimestamp + SHAKE_COUNT_RESET_TIME_MS < now) {
                        mShakeCount = 0;
                    }
    
                    mShakeTimestamp = now;
                    mShakeCount++;
    
                    mListener.onShake(mShakeCount);
                }
            }
        }
    
        private long getSHAKE_SLOP_TIME_MS() {
            // TODO Auto-generated method stub
            return SHAKE_SLOP_TIME_MS;
        }
    
        public void setSHAKE_SLOP_TIME_MS(int sHAKE_SLOP_TIME_MS) {
            SHAKE_SLOP_TIME_MS = sHAKE_SLOP_TIME_MS;
        }   
    
    }
    
    0 讨论(0)
  • 2020-11-22 14:01

    Working with me v.good Reference

    public class ShakeEventListener implements SensorEventListener {
    public final static int SHAKE_LIMIT = 15;
    public final static int LITTLE_SHAKE_LIMIT = 5;
    
    private SensorManager mSensorManager;
    private float mAccel = 0.00f;
    private float mAccelCurrent = SensorManager.GRAVITY_EARTH;
    private float mAccelLast = SensorManager.GRAVITY_EARTH;
    
    private ShakeListener listener;
    
    public interface ShakeListener {
        public void onShake();
        public void onLittleShake();
    }
    
    public ShakeEventListener(ShakeListener l) {
        Activity a = (Activity) l;
        mSensorManager = (SensorManager) a.getSystemService(Context.SENSOR_SERVICE);
        listener = l;
        registerListener();
    }
    
    public ShakeEventListener(Activity a, ShakeListener l) {
        mSensorManager = (SensorManager) a.getSystemService(Context.SENSOR_SERVICE);
        listener = l;
        registerListener();
    }
    
    public void registerListener() {
        mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
    }
    
    public void unregisterListener() {
        mSensorManager.unregisterListener(this);
    }
    
    public void onSensorChanged(SensorEvent se) {
        float x = se.values[0];
        float y = se.values[1];
        float z = se.values[2];
        mAccelLast = mAccelCurrent;
        mAccelCurrent = (float) FloatMath.sqrt(x*x + y*y + z*z);
        float delta = mAccelCurrent - mAccelLast;
        mAccel = mAccel * 0.9f + delta;
        if(mAccel > SHAKE_LIMIT)
            listener.onShake();
        else if(mAccel > LITTLE_SHAKE_LIMIT)
            listener.onLittleShake();
    }
    
    public void onAccuracyChanged(Sensor sensor, int accuracy) {}
    }
    
    0 讨论(0)
  • 2020-11-22 14:03

    You can use seismic. An example can be found here.

    0 讨论(0)
  • 2020-11-22 14:04

    Here is an example code. Put this into your activity class:

      /* put this into your activity class */
      private SensorManager mSensorManager;
      private float mAccel; // acceleration apart from gravity
      private float mAccelCurrent; // current acceleration including gravity
      private float mAccelLast; // last acceleration including gravity
    
      private final SensorEventListener mSensorListener = new SensorEventListener() {
    
        public void onSensorChanged(SensorEvent se) {
          float x = se.values[0];
          float y = se.values[1];
          float z = se.values[2];
          mAccelLast = mAccelCurrent;
          mAccelCurrent = (float) Math.sqrt((double) (x*x + y*y + z*z));
          float delta = mAccelCurrent - mAccelLast;
          mAccel = mAccel * 0.9f + delta; // perform low-cut filter
        }
    
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
        }
      };
    
      @Override
      protected void onResume() {
        super.onResume();
        mSensorManager.registerListener(mSensorListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
      }
    
      @Override
      protected void onPause() {
        mSensorManager.unregisterListener(mSensorListener);
        super.onPause();
      }
    

    And add this to your onCreate method:

        /* do this in onCreate */
        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        mSensorManager.registerListener(mSensorListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
        mAccel = 0.00f;
        mAccelCurrent = SensorManager.GRAVITY_EARTH;
        mAccelLast = SensorManager.GRAVITY_EARTH;
    

    You can then ask "mAccel" wherever you want in your application for the current acceleration, independent from the axis and cleaned from static acceleration such as gravity. It will be approx. 0 if there is no movement, and, lets say >2 if the device is shaked.

    Based on the comments - to test this:

    if (mAccel > 12) {
        Toast toast = Toast.makeText(getApplicationContext(), "Device has shaken.", Toast.LENGTH_LONG);
        toast.show();
    }
    

    Notes:

    The accelometer should be deactivated onPause and activated onResume to save resources (CPU, Battery). The code assumes we are on planet Earth ;-) and initializes the acceleration to earth gravity. Otherwise you would get a strong "shake" when the application starts and "hits" the ground from free-fall. However, the code gets used to the gravitation due to the low-cut filter and would work also on other planets or in free space, once it is initialized. (you never know how long your application will be in use...;-)

    0 讨论(0)
  • 2020-11-22 14:09
     package com.example.shakingapp;
    
    import android.app.Activity;
    import android.graphics.Color;
    import android.hardware.Sensor;
    import android.hardware.SensorEvent;
    import android.hardware.SensorEventListener;
    import android.hardware.SensorManager;
    import android.os.Bundle;
    import android.view.View;
    import android.view.Window;
    import android.view.WindowManager;
    import android.widget.Toast;
    
    
    public class MainActivity extends Activity implements SensorEventListener {
      private SensorManager sensorManager;
      private boolean color = false;
      private View view;
      private long lastUpdate;
    
    
    /** Called when the activity is first created. */
    
      @Override
      public void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        view = findViewById(R.id.textView);
        view.setBackgroundColor(Color.GREEN);
    
        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        lastUpdate = System.currentTimeMillis();
      }
    
      @Override
      public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
          getAccelerometer(event);
        }
    
      }
    
      private void getAccelerometer(SensorEvent event) {
        float[] values = event.values;
        // Movement
        float x = values[0];
        float y = values[1];
        float z = values[2];
    
        System.out.println(x);
        System.out.println(y);
        System.out.println(z);
        System.out.println(SensorManager.GRAVITY_EARTH );
    
        float accelationSquareRoot = (x * x + y * y + z * z)
            / (SensorManager.GRAVITY_EARTH * SensorManager.GRAVITY_EARTH);
    
        long actualTime = System.currentTimeMillis();
        if (accelationSquareRoot >= 2) //
        {
          if (actualTime - lastUpdate < 200) {
            return;
          }
          lastUpdate = actualTime;
          Toast.makeText(this, "Device was shuffed "+accelationSquareRoot, Toast.LENGTH_SHORT)
              .show();
          if (color) {
            view.setBackgroundColor(Color.GREEN);
    
          } else {
            view.setBackgroundColor(Color.RED);
          }
          color = !color;
        }
      }
    
      @Override
      public void onAccuracyChanged(Sensor sensor, int accuracy) {
    
      }
    
      @Override
      protected void onResume() {
        super.onResume();
        // register this class as a listener for the orientation and
        // accelerometer sensors
        sensorManager.registerListener(this,
            sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
            SensorManager.SENSOR_DELAY_NORMAL);
      }
    
      @Override
      protected void onPause() {
        // unregister listener
        super.onPause();
        sensorManager.unregisterListener(this);
      }
    } 
    
    0 讨论(0)
  • 2020-11-22 14:10

    I really liked Peterdk's answer. I took it upon myself to make a coulpe of tweaks to his code .

    file: ShakeDetector.java

    import android.hardware.Sensor;
    import android.hardware.SensorEvent;
    import android.hardware.SensorEventListener;
    import android.hardware.SensorManager;
    import android.util.FloatMath;
    
    public class ShakeDetector implements SensorEventListener {
    
        // The gForce that is necessary to register as shake. Must be greater than 1G (one earth gravity unit)
        private static final float SHAKE_THRESHOLD_GRAVITY = 2.7F;
        private static final int SHAKE_SLOP_TIME_MS = 500;
        private static final int SHAKE_COUNT_RESET_TIME_MS = 3000;
    
        private OnShakeListener mListener;
        private long mShakeTimestamp;
        private int mShakeCount;
    
        public void setOnShakeListener(OnShakeListener listener) {
            this.mListener = listener;
        }
    
        public interface OnShakeListener {
            public void onShake(int count);
        }
    
        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
            // ignore
        }
    
        @Override
        public void onSensorChanged(SensorEvent event) {
    
            if (mListener != null) {
                float x = event.values[0];
                float y = event.values[1];
                float z = event.values[2];
    
                float gX = x / SensorManager.GRAVITY_EARTH;
                float gY = y / SensorManager.GRAVITY_EARTH;
                float gZ = z / SensorManager.GRAVITY_EARTH;
    
                // gForce will be close to 1 when there is no movement.
                float gForce = FloatMath.sqrt(gX * gX + gY * gY + gZ * gZ);
    
                if (gForce > SHAKE_THRESHOLD_GRAVITY) {
                    final long now = System.currentTimeMillis();
                    // ignore shake events too close to each other (500ms)
                    if (mShakeTimestamp + SHAKE_SLOP_TIME_MS > now ) {
                        return;
                    }
    
                    // reset the shake count after 3 seconds of no shakes
                    if (mShakeTimestamp + SHAKE_COUNT_RESET_TIME_MS < now ) {
                        mShakeCount = 0;
                    }
    
                    mShakeTimestamp = now;
                    mShakeCount++;
    
                    mListener.onShake(mShakeCount);
                }
            }
        }
    }
    

    Also, don't forget that you need to register an instance of the ShakeDetector with the SensorManager.

    // ShakeDetector initialization
    mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    mShakeDetector = new ShakeDetector();
    mShakeDetector.setOnShakeListener(new OnShakeListener() {
    
        @Override
        public void onShake(int count) {
                handleShakeEvent(count); 
            }
        });
    
    mSensorManager.registerListener(mShakeDetector, mAccelerometer, SensorManager.SENSOR_DELAY_UI);
    
    0 讨论(0)
提交回复
热议问题