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 встряхиваний.

Благодарю.

0 ответов

Другие вопросы по тегам