摇动监听器检测方向变化

发布于 2024-10-16 13:40:01 字数 3561 浏览 5 评论 0原文

我正在尝试检测应用程序中的摇动事件,以便当用户摇动设备时我能够执行某些操作。但问题是;我使用的 ShakeListener 检测方向变化作为摇动事件。(当我将手机从横向移动到纵向时,它检测到摇动)

我尝试更改力阈值,但当时它无法检测到任何摇动事件。

这是我从 这个网站 获取的 ShakeListener 代码:

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;

public class ShakeListener implements SensorEventListener {
private static final int FORCE_THRESHOLD = 500;
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;
}

public void setOnShakeListener(OnShakeListener listener) {
    mShakeListener = listener;
}

public void resume(OnShakeListener listener) {
    this.setOnShakeListener(listener);
    mSensorMgr = (SensorManager) mContext
            .getSystemService(Context.SENSOR_SERVICE);
    if (mSensorMgr == null) {
        throw new UnsupportedOperationException("Sensors not supported");
    }

    boolean supported = mSensorMgr.registerListener(this,
            mSensorMgr.getDefaultSensor(SensorManager.SENSOR_ACCELEROMETER),
            SensorManager.SENSOR_DELAY_UI);

    if (!supported) {
        mSensorMgr.unregisterListener(this,
                mSensorMgr.getDefaultSensor(SensorManager.SENSOR_ACCELEROMETER));
        throw new UnsupportedOperationException(
                "Accelerometer not supported");
    }
}

public void pause() {
    mShakeListener = null;
    if (mSensorMgr != null) {
        mSensorMgr.unregisterListener(this,
                mSensorMgr.getDefaultSensor(SensorManager.SENSOR_ACCELEROMETER));
        mSensorMgr = null;
    }
}

public void onAccuracyChanged(Sensor sensor, int accuracy) {
    // TODO Auto-generated method stub

}

public void onSensorChanged(SensorEvent event) {
    if (event.sensor.getType() != 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(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;
                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];
    }

}
}

我只想检测摇晃运动,而不是方向变化。

有什么建议吗?

I'm trying to detect shake events in my application so that I would be able to do something when user shakes the device. But the problem is; ShakeListener which I used, detects orientation changes as a shake event.(When I move the phone from landscape to portrait, it detects a shake)

I tried changing the force threshold but at that time it can't detect any shake event.

Here is the ShakeListener code which i took from this site :

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;

public class ShakeListener implements SensorEventListener {
private static final int FORCE_THRESHOLD = 500;
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;
}

public void setOnShakeListener(OnShakeListener listener) {
    mShakeListener = listener;
}

public void resume(OnShakeListener listener) {
    this.setOnShakeListener(listener);
    mSensorMgr = (SensorManager) mContext
            .getSystemService(Context.SENSOR_SERVICE);
    if (mSensorMgr == null) {
        throw new UnsupportedOperationException("Sensors not supported");
    }

    boolean supported = mSensorMgr.registerListener(this,
            mSensorMgr.getDefaultSensor(SensorManager.SENSOR_ACCELEROMETER),
            SensorManager.SENSOR_DELAY_UI);

    if (!supported) {
        mSensorMgr.unregisterListener(this,
                mSensorMgr.getDefaultSensor(SensorManager.SENSOR_ACCELEROMETER));
        throw new UnsupportedOperationException(
                "Accelerometer not supported");
    }
}

public void pause() {
    mShakeListener = null;
    if (mSensorMgr != null) {
        mSensorMgr.unregisterListener(this,
                mSensorMgr.getDefaultSensor(SensorManager.SENSOR_ACCELEROMETER));
        mSensorMgr = null;
    }
}

public void onAccuracyChanged(Sensor sensor, int accuracy) {
    // TODO Auto-generated method stub

}

public void onSensorChanged(SensorEvent event) {
    if (event.sensor.getType() != 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(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;
                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];
    }

}
}

I want to detect only shake movements, not orientation changes.

Any suggestion?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心作怪 2024-10-23 13:40:01

您可能必须取消注册传感器侦听器,然后将用于确定“摇动事件”的值归零/归零/重新初始化。然后重新注册您的监听器。

方向更改会触发 onDestroy,然后触发 onCreate

You will probably have to unregister your sensor listener followed by zeroing/nulling/reinitializing the values you use to determine a "shake event." Then re-register your listener.

An orienatation change triggers onDestroy followed by onCreate.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文