Оператор if с использованием запускаемого обработчика - PullRequest
0 голосов
/ 27 февраля 2019

Я создаю приложение для Android и добавляю функцию встряхивания, используя библиотеку сейсмики https://github.com/square/seismic

С помощью этой функции встряски я пытаюсь сделать так, чтобы в зависимости от количества каждого встряхивания она былаоткройте соответствующую страницу, т. е. встряхните один раз для страницы 1, дважды встряхните для страницы 2. и т. д.

Я использую обработчик, чтобы подождать 1700 мс, прежде чем инициировать оператор if, чтобы он знал правильный счет, а не прямойУйдя к первому оператору if (когда count равен 1), но он все еще переходит со страницы 1 на страницу 2 на страницу 3, вместо того, чтобы ждать и переходить на правильную страницу в первый раз.

Домашний класс

mShakeDetector.setOnShakeListener(new com.example.name.project.ShakeDetector.OnShakeListener() {

            @Override
            public void onShake(final int count) {
                System.out.println(count);

                final Intent tts = new Intent(context, ttsScreen.class);
                final Intent stt = new Intent(context, sttScreen.class);
                final Intent cbb = new Intent(context, cbbScreen.class);
                final Intent ocr = new Intent(context, ocrScreen.class);

                Handler handler = new Handler();
                handler.postDelayed(new Runnable() {
                    public void run() {
                        if( count == 1 ) {
                            startActivity(tts);
                        }
                        else if (count == 2) {
                            startActivity(stt);
                        }
                        else if (count == 3) {
                            startActivity(cbb);
                        }
                        else if (count == 4) {
                            startActivity(ocr);
                        }
                    }
                }, 1800);



            }
        });

Класс ShakeDetector

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.FloatMath;

public class ShakeDetector implements SensorEventListener {

    /*
     * The gForce that is necessary to register as shake.
     * Must be greater than 1G (one earth gravity unit).
     * You can install "G-Force", by Blake La Pierre
     * from the Google Play Store and run it to see how
     *  many G's it takes to register a shake
     */
    private static final float SHAKE_THRESHOLD_GRAVITY = 2.7F;
    private static final int SHAKE_SLOP_TIME_MS = 500;
    private static final int SHAKE_COUNT_RESET_TIME_MS = 3000;

    private OnShakeListener mListener;
    private long mShakeTimestamp;
    private int mShakeCount;

    public void setOnShakeListener(OnShakeListener listener) {
        this.mListener = listener;
    }

    public interface OnShakeListener {
        public void onShake(int count);
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // ignore
    }

    @Override
    public void onSensorChanged(SensorEvent event) {

        if (mListener != null) {
            float x = event.values[0];
            float y = event.values[1];
            float z = event.values[2];

            float gX = x / SensorManager.GRAVITY_EARTH;
            float gY = y / SensorManager.GRAVITY_EARTH;
            float gZ = z / SensorManager.GRAVITY_EARTH;

            // gForce will be close to 1 when there is no movement.
            float gForce = (float)Math.sqrt( gX * gX + gY * gY + gZ * gZ );


            if (gForce > SHAKE_THRESHOLD_GRAVITY) {
                final long now = System.currentTimeMillis();
                // ignore shake events too close to each other (500ms)
                if (mShakeTimestamp + SHAKE_SLOP_TIME_MS > now) {
                    return;
                }

                // reset the shake count after 3 seconds of no shakes
                if (mShakeTimestamp + SHAKE_COUNT_RESET_TIME_MS < now) {
                    mShakeCount = 0;
                }

                mShakeTimestamp = now;
                mShakeCount++;

                mListener.onShake(mShakeCount);
            }
        }
    }
}

Таким образом, по существу, класс детектора встряхиваний регистрирует счетчики встряхиваний в течение 3 секунд перед сбросом, что хорошо, но теперь в моемДомашний класс, я хочу, чтобы он регистрировал мои встряски, подождите X секунд, а затем правильно открыл класс, но я не уверен, что не так с моим подходом?

Я добавилсистема вне счета, и ее обнаружение трясется нормально

I/System.out: 1 I/System.out: 2 I/System.out: 3

Но она переходит со страницы 1 на страницу 2 на страницу 3 (вы можете видеть переходы);в чем причина?

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

onShake вызывает несколько раз для каждого встряхивания.Первая проблема: вы публикуете Runnable каждый раз, но вызывается onShake(), но вы не отменили последнюю.Поэтому вам нужно отменить последний Runnable в очереди, прежде чем отправлять новый.Попробуйте приведенный ниже код: -

public class MainActivity extends AppCompatActivity {
private int shakeCount=0;
private Runnable runnable ;
private Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    runnable =new Runnable() {
        public void run() {
            if( shakeCount == 1 ) {
                final Intent tts = new Intent(context, ttsScreen.class);
                startActivity(tts);
            }
            else if (shakeCount == 2) {
                final Intent stt = new Intent(context, sttScreen.class);
                startActivity(stt);
            }
            else if (shakeCount == 3) {
                final Intent cbb = new Intent(context, cbbScreen.class);
                startActivity(cbb);
            }
            else if (shakeCount == 4) {
                final Intent ocr = new Intent(context, ocrScreen.class);
                startActivity(ocr);
            }
            shakeCount=0;
        }
    };
    mShakeDetector.setOnShakeListener(new com.example.name.project.ShakeDetector.OnShakeListener() {
        @Override
        public void onShake(final int count) {
            shakeCount=count;
            handler.removeCallbacks(runnable);
            handler.postDelayed(runnable, 1800);

    });
}

Я поместил там класс Activity только для разграничения локальной и глобальной переменной.

0 голосов
/ 27 февраля 2019

Я полагаю, вы устанавливаете тайм-аут не в том месте.Вы запускаете событие 3 раза, каждый раз, когда увеличивается счет.

Ваш OnShakeListener должен скорее содержать счет.OnShake должен позаботиться об обновлении счетчика в слушателе и запустить обработчик после некоторого времени ожидания и сбросить счетчик встряхиваний.

...