OnShakeListener onSensorChanged вызывается несколько раз
Я хочу, чтобы мое приложение распознавало тряску телефона, и когда это происходит 4 раза менее чем за 1 секунду, запускает действие. Теперь я сталкиваюсь с проблемой, заключающейся в том, что я добавил несколько строк журнала, чтобы увидеть, что происходит, и функция onSensorChanged в Shake Listener вызывается несколько раз. Это нормально? Его следует запускать только при обнаружении сотрясения, но он вызывается буквально все время:
Журнал:
10-31 11:01:01.658 3375-3375/ D/SWITCH_LOG: onSensorChanged
10-31 11:01:01.733 3375-3375/ D/SWITCH_LOG: onSensorChanged
10-31 11:01:01.771 3375-3375/ D/SWITCH_LOG: onSensorChanged
10-31 11:01:01.836 3375-3375/ D/SWITCH_LOG: onSensorChanged
10-31 11:01:01.901 3375-3375/ D/SWITCH_LOG: onSensorChanged
10-31 11:01:01.966 3375-3375/ D/SWITCH_LOG: onSensorChanged
10-31 11:01:02.032 3375-3375/ D/SWITCH_LOG: onSensorChanged
10-31 11:01:02.103 3375-3375/ D/SWITCH_LOG: onSensorChanged
10-31 11:01:02.165 3375-3375/ D/SWITCH_LOG: onSensorChanged
10-31 11:01:02.227 3375-3375/ D/SWITCH_LOG: onSensorChanged
10-31 11:01:02.291 3375-3375/ D/SWITCH_LOG: onSensorChanged
10-31 11:01:02.357 3375-3375/ D/SWITCH_LOG: onSensorChanged
10-31 11:01:02.421 3375-3375/ D/SWITCH_LOG: onSensorChanged
10-31 11:01:02.486 3375-3375/ D/SWITCH_LOG: onSensorChanged
10-31 11:01:02.551 3375-3375/ D/SWITCH_LOG: onSensorChanged
10-31 11:01:02.616 3375-3375/ D/SWITCH_LOG: onSensorChanged
10-31 11:01:02.681 3375-3375/ D/SWITCH_LOG: onSensorChanged
И т.п.
ShakeEventListener:
public class ShakeEventListener implements SensorEventListener {
private Helper helper;
private SensorManager sensorManager;
private Sensor sensor;
public ShakeEventListener (Context context){
helper = new Helper(context.getApplicationContext());
/*sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
if (sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null){
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
}*/
}
/** Minimum movement force to consider. */
private static final int MIN_FORCE = 10;
/**
* Number of times in a shake gesture that the direction of movement needs to
* change.
*/
private static final int DIRECTION_CHANGE = 4;
/** Maximum pause between movements. */
private static final int MAX_PAUSE_BETHWEEN_DIRECTION_CHANGE = 500;
/** Minimum allowed time for shake gesture. */
private static final int MIN_TOTAL_DURATION_OF_SHAKE = 500; // 0,5 seconds
/** Maximum allowed time for shake gesture. */
private static final int MAX_TOTAL_DURATION_OF_SHAKE = 1000; // 1 seconds
/** Time when the gesture started. */
private long mFirstDirectionChangeTime = 0;
/** Time when the last movement started. */
private long mLastDirectionChangeTime;
/** How many movements are considered so far. */
private int mDirectionChangeCount = 0;
/** The last x position. */
private float lastX = 0;
/** The last y position. */
private float lastY = 0;
/** The last z position. */
private float lastZ = 0;
/** OnShakeListener that is called when shake is detected. */
private OnShakeListener mShakeListener;
/**
* Interface for shake gesture.
*/
public interface OnShakeListener {
/**
* Called when shake gesture is detected.
*/
void onShake();
}
public void setOnShakeListener(OnShakeListener listener) {
mShakeListener = listener;
}
@Override
public void onSensorChanged(SensorEvent se) {
helper.logD("onSensorChanged");
// get sensor data
float x = se.values[SensorManager.DATA_X];
float y = se.values[SensorManager.DATA_Y];
float z = se.values[SensorManager.DATA_Z];
// helper.logD("x, y, z = " + x + ", " + y + ", " + z);
// calculate movement
float totalMovement = Math.abs(x + y + z - lastX - lastY - lastZ);
if (totalMovement > MIN_FORCE) {
helper.logD("totalMovement = " + totalMovement + ", MIN_FORCE = " + MIN_FORCE);
// get time
long now = System.currentTimeMillis();
// store first movement time
if (mFirstDirectionChangeTime == 0) {
mFirstDirectionChangeTime = now;
mLastDirectionChangeTime = now;
}
// check if the last movement was not long ago
long lastChangeWasAgo = now - mLastDirectionChangeTime;
if (lastChangeWasAgo < MAX_PAUSE_BETHWEEN_DIRECTION_CHANGE) {
helper.logD("lastChangeWasAgo = " + lastChangeWasAgo + ", MAX_PAUSE_BETHWEEN_DIRECTION_CHANGE = " + MAX_PAUSE_BETHWEEN_DIRECTION_CHANGE);
// store movement data
mLastDirectionChangeTime = now;
mDirectionChangeCount++;
helper.logD("mDirectionChangeCount = " + mDirectionChangeCount);
// store last sensor data
lastX = x;
lastY = y;
lastZ = z;
// check how many movements are so far
//if (mDirectionChangeCount >= DIRECTION_CHANGE) {
if (mDirectionChangeCount == DIRECTION_CHANGE) {
//mShakeListener.onShake();
// check total duration
long totalDuration = now - mFirstDirectionChangeTime;
if (totalDuration <= MAX_TOTAL_DURATION_OF_SHAKE) {
helper.logD("onShake called");
mShakeListener.onShake();
//resetShakeParameters();
}
resetShakeParameters();
}
} else {
resetShakeParameters();
}
}
}
/**
* Resets the shake parameters to their default values.
*/
private void resetShakeParameters() {
helper.logD("resetShakeParameters");
mFirstDirectionChangeTime = 0;
mDirectionChangeCount = 0;
mLastDirectionChangeTime = 0;
lastX = 0;
lastY = 0;
lastZ = 0;
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
И на самом деле этот код не совсем то, что я хочу: иногда я перемещаю телефон 1 раз, и он запускает функцию (определенную где-то еще), иногда я поднимаю телефон со стола, и он запускает функцию. Однако его следует запускать только после 4 встряхиваний.
Благодарю.