Android:摇检测器太敏感
我试图检测摇 - 我使用下面的代码, 它工作得很好,但在某些设备(例如银河注2),它检测到摇晃过早(在某些情况下 - 当我只是抱着还在电话)Android:摇检测器太敏感
main.java:
ShakeListener mShaker = new ShakeListener(this);
mShaker.setOnShakeListener(new ShakeListener.OnShakeListener() {
public void onShake()
{
// Some code...
}
});
}
ShakeListener.java:
package com.my.app;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.widget.Toast;
import android.content.Context;
import java.lang.UnsupportedOperationException;
public class ShakeListener implements SensorEventListener
{
private static final int FORCE_THRESHOLD = 700;
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 = 5;
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 = false;
try {
supported = mSensorMgr.registerListener(this, mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);
} catch (Exception e) {Toast.makeText(mContext, "Shaking not supported", Toast.LENGTH_LONG).show();}
if ((!supported)&&(mSensorMgr != null)) mSensorMgr.unregisterListener(this);
}
public void pause() {
if (mSensorMgr != null) {
mSensorMgr.unregisterListener(this);
mSensorMgr = null;
}
}
public void onAccuracyChanged(Sensor sensor, int accuracy) { }
public void onSensorChanged(SensorEvent event)
{
if (event.sensor.getType() != Sensor.TYPE_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(event.values[0] + event.values[1] + event.values[2] - 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 = event.values[0];
mLastY = event.values[1];
mLastZ = event.values[2];
}
}
}
检查加速具有较高数量的抖动造成的。看看这个代码适用于我。
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
if (mAccel > 8) {
Toast.makeText(getApplicationContext(),
"You have shaken your phone", Toast.LENGTH_SHORT).show();
}
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
Log.i("Sensor", "mAccel" + mAccel);
}
};
如果你有灵敏度控制,所以PLZ解释灵敏度控制的价值变化 – 2013-12-05 06:45:07
这将检测任何突然的SINGLE运动,这可能不是一个摇晃 - 只要放下手机将激活它。 – CloudWalker 2014-07-09 09:01:30
开始从较低的灵敏度,但如果逐渐增加SHA它超过某个初始阈值的国王会持续更长的时间。这与人类的看法很相似。
它在其他手机中工作正常的问题。 .. – Erez 2013-02-14 16:18:09
试试这个...,让我知道..
public class ShakeListener implements SensorEventListener {
private String TAG = ShakeListener.class.getSimpleName();
private static final int FORCE_THRESHOLD = 800;
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 = 5;
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) {
Log.d(TAG,"ShakeListener invoked---->");
mContext = context;
resume();
}
public void setOnShakeListener(OnShakeListener listener) {
Log.d(TAG,"ShakeListener setOnShakeListener invoked---->");
mShakeListener = listener;
}
public void resume() {
mSensorMgr = (SensorManager) mContext
.getSystemService(Context.SENSOR_SERVICE);
if (mSensorMgr == null) {
throw new UnsupportedOperationException("Sensors not supported");
}
boolean supported = false;
try {
supported = mSensorMgr.registerListener(this,
mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_GAME);
} catch (Exception e) {
Toast.makeText(mContext, "Shaking not supported", Toast.LENGTH_LONG)
.show();
}
if ((!supported) && (mSensorMgr != null))
mSensorMgr.unregisterListener(this);
}
public void pause() {
if (mSensorMgr != null) {
mSensorMgr.unregisterListener(this);
mSensorMgr = null;
}
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() != Sensor.TYPE_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(event.values[SensorManager.DATA_X]
+ event.values[SensorManager.DATA_Y]
+ event.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;
Log.d(TAG,"ShakeListener mShakeListener---->"+mShakeListener);
if (mShakeListener != null) {
mShakeListener.onShake();
}
}
mLastForce = now;
}
mLastTime = now;
mLastX = event.values[SensorManager.DATA_X];
mLastY = event.values[SensorManager.DATA_Y];
mLastZ = event.values[SensorManager.DATA_Z];
}
}
}
这正常工作与我:
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) {}
}
怎么样通过增量multiplaying比例呢? – 2013-02-14 15:57:30
试试这个。 http://stackoverflow.com/questions/2317428/android-i-want-to-shake-it – 2013-03-01 13:22:49
如果你已经完成了灵敏度控制,所以PLZ解释谁为灵敏度控制值变化 – 2013-12-05 06:44:43