最近接到需求实现摇一摇需求,不过这个法律限制的很严格,属于敏感地带,实现后又被叫停了。
法律要求:
如果按照规定,操作时间不少于3s就基本没什么跳转了。
实现的话,只考虑了第一条,即:x,y,z只要有一个方向重力加速度大于15就可以跳转。
工具类:
public class ShakeUtils implements SensorEventListener {
private ArrayList<OnShakeListener> mOnShakeListeners = null;
// 触发Shake的最小时间间隔
// private static final int MIN_SHAKE_INTERVAL = 1024;
private static final int MIN_SHAKE_INTERVAL = 500;
// 上次触发Shake操作的时间
private long mLastShakeTime = 0L;
private long mLastUpdateTime = 0L;
// 两次摇晃的最小时间间隔
private static final int SHAKE_INTERVAL_MILLSECOND = 55;
// 上次摇晃的重力坐标位置
private float mLastX = 0;
private float mLastY = 0;
private float mLastZ = 0;
public interface OnShakeListener {
void onShake();
}
private SensorManager mSensorManager;
public ShakeUtils() {
Context context = App.getInstance();
mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_UI);
mOnShakeListeners = new ArrayList<>();
}
public void bindShakeListener(OnShakeListener listener) {
if (listener != null) {
mOnShakeListeners.add(listener);
}
}
// 销毁
public void unBindShakeListener(OnShakeListener listener) {
if (mOnShakeListeners != null) {
mOnShakeListeners.remove(listener);
}
if (mSensorManager != null) {
mSensorManager.unregisterListener(this);
}
}
@Override
public void onSensorChanged(SensorEvent event) {
if (event == null) {
return;
}
long curUpdateTime = System.currentTimeMillis();
// 两次位置改变的时间间隔
long timeInterval = curUpdateTime - mLastUpdateTime;
if (timeInterval < SHAKE_INTERVAL_MILLSECOND) {
return;
}
if (event.values.length < 3) {
return;
}
mLastUpdateTime = curUpdateTime;
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
float deltaX = x - mLastX;
float deltaY = y - mLastY;
float deltaZ = z - mLastZ;
mLastX = x;
mLastY = y;
mLastZ = z;
// 法律要求不低于15
// 如果不敏感请自行调低该数值,低于10的话就不行了,因为z轴上的加速度本身就已经达到10了
int medumValue = 16;
// 只要有一个重力加速度大于16就可以
if (Math.abs(x) > medumValue || Math.abs(y) > medumValue || Math.abs(z) > medumValue) {
// DebugUtil.error("---onShake speed- x轴方向的重力加速度" + Math.abs(x) + ";y轴方向的重力加速度" + Math.abs(y) + ";z轴方向的重力加速度" + Math.abs(z));
startShake();
}
// 如果使用这个方式,建议值是450,或者500
// double speed = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ) * 1000.0 / timeInterval;
// if (speed >= SPEED_SHAKE_MILLSECONDS) {
// startShake(speed);
// }
}
private void startShake() {
long curShakeTime = System.currentTimeMillis();
if (curShakeTime - mLastShakeTime < MIN_SHAKE_INTERVAL) {
return;
}
mLastShakeTime = curShakeTime;
if (mOnShakeListeners != null) {
for (int i = 0; i < mOnShakeListeners.size(); i++) {
mOnShakeListeners.get(i).onShake();
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
直接放在Activity上即可。