我需要添加一个摇功能,将刷新我的Android应用程序。

我所找到的所有文档都涉及实现SensorListener,但Eclipse告诉我它已被弃用,并建议使用SensorEventListener。

有人知道如何创建这个震动控制器吗?


当前回答

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();
    }


}

玩得开心。

其他回答

下面是另一个代码:

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);
            }
        }
    }

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();
    }


}

玩得开心。

我写了一个检测垂直和水平震动并显示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();
            }
        }
    }
}
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;
    }   

}
// 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;
    }
}
}
}