如何检测与Android的摇动事件?

我如何检测与Android的摇一摇事件? 我如何检测摇动方向?

发生抖动时,我想在图像视图中更改图像。

从代码的angular度来看,您需要实现SensorListener:

public class ShakeActivity extends Activity implements SensorListener 

您将需要获取SensorManager:

 sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE); 

并注册这个传感器所需的标志:

 sensorMgr.registerListener(this, SensorManager.SENSOR_ACCELEROMETER, SensorManager.SENSOR_DELAY_GAME); 

在你的onSensorChange()方法中,你可以确定它是否动摇:

 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) { Log.d("sensor", "shake detected w/ speed: " + speed); Toast.makeText(this, "shake detected w/ speed: " + speed, Toast.LENGTH_SHORT).show(); } last_x = x; last_y = y; last_z = z; } } } 

振动阈值定义为:

 private static final int SHAKE_THRESHOLD = 800; 

还有一些其他的方法来检测摇动。 看这个链接。 (如果该链接不起作用或链接已经死亡,请查看此Web档案 )。

看看这个例子为Android摇摆侦测侦听器。

注意: SensorListener已弃用。 我们可以改用SensorEventListener 。 这是一个使用SensorEventListener的简单例子。

谢谢。

谷歌帮助了很多 。 你也需要接受答案,以获得更好的帮助。

 /* The following code was written by Matthew Wiggins * and is released under the APACHE 2.0 license * * http://www.apache.org/licenses/LICENSE-2.0 */ package com.hlidskialf.android.hardware; import android.hardware.SensorListener; import android.hardware.SensorManager; import android.content.Context; import java.lang.UnsupportedOperationException; public class ShakeListener implements SensorListener { private static final int FORCE_THRESHOLD = 350; private static final int TIME_THRESHOLD = 100; private static final int SHAKE_TIMEOUT = 500; private static final int SHAKE_DURATION = 1000; private static final int SHAKE_COUNT = 3; private SensorManager mSensorMgr; private float mLastX=-1.0f, mLastY=-1.0f, mLastZ=-1.0f; private long mLastTime; private OnShakeListener mShakeListener; private Context mContext; private int mShakeCount = 0; private long mLastShake; private long mLastForce; public interface OnShakeListener { public void onShake(); } public ShakeListener(Context context) { mContext = context; resume(); } public void setOnShakeListener(OnShakeListener listener) { mShakeListener = listener; } public void resume() { mSensorMgr = (SensorManager)mContext.getSystemService(Context.SENSOR_SERVICE); if (mSensorMgr == null) { throw new UnsupportedOperationException("Sensors not supported"); } boolean supported = mSensorMgr.registerListener(this, SensorManager.SENSOR_ACCELEROMETER, SensorManager.SENSOR_DELAY_GAME); if (!supported) { mSensorMgr.unregisterListener(this, SensorManager.SENSOR_ACCELEROMETER); throw new UnsupportedOperationException("Accelerometer not supported"); } } public void pause() { if (mSensorMgr != null) { mSensorMgr.unregisterListener(this, SensorManager.SENSOR_ACCELEROMETER); mSensorMgr = null; } } public void onAccuracyChanged(int sensor, int accuracy) { } public void onSensorChanged(int sensor, float[] values) { if (sensor != SensorManager.SENSOR_ACCELEROMETER) return; long now = System.currentTimeMillis(); if ((now - mLastForce) > SHAKE_TIMEOUT) { mShakeCount = 0; } if ((now - mLastTime) > TIME_THRESHOLD) { long diff = now - mLastTime; float speed = Math.abs(values[SensorManager.DATA_X] + values[SensorManager.DATA_Y] + values[SensorManager.DATA_Z] - mLastX - mLastY - mLastZ) / diff * 10000; if (speed > FORCE_THRESHOLD) { if ((++mShakeCount >= SHAKE_COUNT) && (now - mLastShake > SHAKE_DURATION)) { mLastShake = now; mShakeCount = 0; if (mShakeListener != null) { mShakeListener.onShake(); } } mLastForce = now; } mLastTime = now; mLastX = values[SensorManager.DATA_X]; mLastY = values[SensorManager.DATA_Y]; mLastZ = values[SensorManager.DATA_Z]; } } } 

您也可以看看JakeWharton图书馆的代码示例: https : //github.com/square/seismic

这个问题已经有很多的解决方法,但是我想发布一个(1)不使用API​​ 3中描述的库,(2)正确计算加速度的大小,以及(3)正确应用震动事件之间的超时。 这是一个解决scheme:

 // variables for shake detection private static final float SHAKE_THRESHOLD = 3.25f; // m/S**2 private static final int MIN_TIME_BETWEEN_SHAKES_MILLISECS = 1000; private long mLastShakeTime; private SensorManager mSensorMgr; 

初始化定时器:

  // Get a sensor manager to listen for shakes mSensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE); // Listen for shakes Sensor accelerometer = mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); if (accelerometer != null) { mSensorMgr.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL); } 

SensorEventListener方法覆盖:

 @Override public void onSensorChanged(SensorEvent event) { if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { long curTime = System.currentTimeMillis(); if ((curTime - mLastShakeTime) > MIN_TIME_BETWEEN_SHAKES_MILLISECS) { float x = event.values[0]; float y = event.values[1]; float z = event.values[2]; double acceleration = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2)) - SensorManager.GRAVITY_EARTH; Log.d(APP_NAME, "Acceleration is " + acceleration + "m/s^2"); if (acceleration > SHAKE_THRESHOLD) { mLastShakeTime = curTime; Log.d(APP_NAME, "Shake, Rattle, and Roll"); } } } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { // Ignore } 

当你全部完成

  // Stop listening for shakes mSensorMgr.unregisterListener(this); 

由于SensorListener弃用,因此请使用以下代码:

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

然后:

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

详细的问题可以在这里find:

Android:我想动摇它

执行以下操作:

 private float xAccel, yAccel, zAccel; private float xPreviousAccel, yPreviousAccel, zPreviousAccel; private boolean firstUpdate = true; private final float shakeThreshold = 1.5f; private boolean shakeInitiated = false; SensorEventListener mySensorEventListener; SensorManager mySensorManager; 

把这个放在创build方法上。

 mySensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); mySensorManager.registerListener(mySensorEventListener, mySensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL); 

现在是主要部分。

 private boolean isAccelerationChanged() { float deltaX = Math.abs(xPreviousAccel - xAccel); float deltaY = Math.abs(yPreviousAccel - yAccel); float deltaZ = Math.abs(zPreviousAccel - zAccel); return (deltaX > shakeThreshold && deltaY > shakeThreshold) || (deltaX > shakeThreshold && deltaZ > shakeThreshold) || (deltaY > shakeThreshold && deltaZ > shakeThreshold); } private void updateAccelParameters(float xNewAccel, float yNewAccel, float zNewAccel) { if (firstUpdate) { xPreviousAccel = xNewAccel; yPreviousAccel = yNewAccel; zPreviousAccel = zNewAccel; firstUpdate = false; }else{ xPreviousAccel = xAccel; yPreviousAccel = yAccel; zPreviousAccel = zAccel; } xAccel = xNewAccel; yAccel = yNewAccel; zAccel = zNewAccel; } private void executeShakeAction() { //this method is called when devices shakes } public void onSensorChanged(SensorEvent se) { updateAccelParameters(se.values[0], se.values[1], se.values[2]); if ((!shakeInitiated) && isAccelerationChanged()) { shakeInitiated = true; }else if ((shakeInitiated) && isAccelerationChanged()){ executeShakeAction(); }else if((shakeInitiated) && (!isAccelerationChanged())){ shakeInitiated = false; } } public void onAccuracyChanged(Sensor sensor, int accuracy) { //setting the accuracy } 

在你的MainActivity java文件中:
不要忘记添加这个代码:

MainActivity.java

  mShaker = new ShakeListener(this); mShaker.setOnShakeListener(new ShakeListener.OnShakeListener () { public void onShake() { Toast.makeText(MainActivity.this, "Shake " , Toast.LENGTH_LONG).show(); } }); } @Override protected void onResume() { super.onResume(); mShaker.resume(); } @Override protected void onPause() { super.onPause(); mShaker.pause(); 

或者我给你一个关于这个东西的链接 。
问候,
多尼