CountDownTimer добавляет время с каждым циклом - PullRequest
1 голос
/ 27 сентября 2019

Я работаю над фрагментом, который включает два таймера, которые принимают пользовательский ввод.Таймер B связан с таймером A так, что, когда таймер A запускается, то же самое происходит и с таймером B. Назначение таймера A - один обратный отсчет.Назначение таймера B - обратный отсчет, один раз звуковой сигнал в 0, сброс к исходному значению и повтор.У меня проблема в том, что, когда таймер B достигает 0, он не сбрасывается и сразу не начинает обратный отсчет.Таймер, кажется, задерживается еще больше, вызывая ToneGenerator.Это приводит к тому, что два таймера становятся все более рассинхронизированными каждый раз при сбросе таймера B.

Например, скажем, таймер A установлен на 10 секунд, а таймер B на 2 секунды.

- Таймеры запускаются -

Таймер A: 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0

Таймер B: 2, 1,0, 2, 1, 0, 2, 1, 0, 2, 1

Таймер подает звуковой сигнал только 3 раза (когда таймер B установлен на 0,), когда он должен подавать звуковой сигнал 5 раз (5 наборов по 2 секундыинтервалы = 10 секунд: значение таймера A.) Другими словами, я бы хотел, чтобы таймер B издал звуковой сигнал, когда таймер A имеет значения 8, 6, 4, 2 и 0.

Как мне добитьсяэто?

Я проконсультировался на форумах YT и попытался поиграться со значением для millisInFuture.

Фрагмент

public class fragmentdro extends Fragment {
    private EditText session_edit_text;
    private EditText dro_edit_text;
    private TextView session_text_view;
    private TextView dro_text_view;
    private Button session_start_button;
    private Button dro_start_button;
    private Button session_reset_button;
    private Button dro_reset_button;
    private Button session_set_button;
    private Button dro_set_button;
    private CountDownTimer sessionTimer;
    private CountDownTimer droTimer;
    private boolean SessionTimerRunning;
    private boolean DROTimerRunning;
    private long SessionStartTimeInMillis;
    private long DROStartTimeInMillis;
    private long SessionTimeLeftInMillis = SessionStartTimeInMillis;
    private long DROTimeLeftInMillis = DROStartTimeInMillis;
    private long SessionEndTime;
    private long DROEndTime;
    View View;

    public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @NonNull Bundle savedInstanceState) {
        View = inflater.inflate(R.layout.dro_fragment, container, false);

        session_edit_text = View.findViewById(R.id.session_edit_text);
        dro_edit_text = View.findViewById(R.id.dro_edit_text);
        session_text_view = View.findViewById(R.id.session_text_view);
        dro_text_view = View.findViewById(R.id.dro_text_view);
        session_start_button = View.findViewById(R.id.session_start_button);
        dro_start_button = View.findViewById(R.id.dro_start_button);
        session_reset_button = View.findViewById(R.id.session_reset_button);
        dro_reset_button = View.findViewById(R.id.dro_reset_button);
        session_set_button = View.findViewById(R.id.session_set_button);
        dro_set_button = View.findViewById(R.id.dro_set_button);
        InputMethodManager imm = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
        ToneGenerator toneGenerator = new ToneGenerator(AudioManager.STREAM_ALARM, 100);

Таймер A

session_set_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(android.view.View view) {
                String Sessioninput = session_edit_text.getText().toString();
                if (Sessioninput.length() == 0) {
                    Toast.makeText(getActivity(), "Fill it in", Toast.LENGTH_SHORT).show();
                    return;
                }
                long millisInput = Long.parseLong(Sessioninput) * 1000;
                if (millisInput == 0) {
                    Toast.makeText(getActivity(), "Please enter a positive number", Toast.LENGTH_SHORT).show();
                    return;
                }
                setSessionTime(millisInput);
                session_edit_text.setText("");
                imm.hideSoftInputFromWindow(getView().getWindowToken(), 0);
            }
        });

        session_start_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(android.view.View view) {
                if (SessionTimerRunning) {
                    pauseSessionTimer();
                    resetDROTimer();
                } else {
                    startSessionTimer();
                    startDROTimer();
                }
            }
        });

        session_reset_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(android.view.View view) {
                if (SessionTimerRunning) {
                    resetSessionTimer();
                } else {
                    resetSessionTimer();
                }
            }
        });

  public void setSessionTime(long milliseconds) {
        SessionStartTimeInMillis = milliseconds;
        resetSessionTimer();
    }

    public void startSessionTimer() {
        SessionEndTime = System.currentTimeMillis() + SessionTimeLeftInMillis;
        sessionTimer = new CountDownTimer(SessionTimeLeftInMillis, 100) {
            @Override
            public void onTick(long millisUntilFinished) {
                SessionTimeLeftInMillis = millisUntilFinished;
                updateSessionText();
            }

            @Override
            public void onFinish() {
                SessionTimerRunning = false;
                session_start_button.setText("Start");
                session_start_button.setVisibility(android.view.View.INVISIBLE);
                session_reset_button.setVisibility(android.view.View.VISIBLE);
            }
        }.start();

        SessionTimerRunning = true;
        session_start_button.setText("Pause");
    }

    public void pauseSessionTimer() {
        sessionTimer.cancel();
        droTimer.cancel();
        SessionTimerRunning = false;
        DROTimerRunning = false;
        session_start_button.setText("Start");
        updateSessionText();
    }

    public void resetSessionTimer() {
        if (SessionTimerRunning) {
            sessionTimer.cancel();
            SessionTimeLeftInMillis = (SessionStartTimeInMillis);
            updateSessionInterface();
            startSessionTimer();
        } else {
            SessionTimeLeftInMillis = (SessionStartTimeInMillis);
            updateSessionText();
            updateSessionInterface();
            session_reset_button.setVisibility(android.view.View.VISIBLE);
            session_start_button.setVisibility(android.view.View.VISIBLE);
        }
    }

    public void updateSessionText() {
        int minutes = (int) (SessionTimeLeftInMillis/1000/60);
        int seconds = (int) (SessionTimeLeftInMillis/1000)%60;

        String timeLeftFormatted = String.format(Locale.getDefault(),
                timeLeftFormatted = String.format(Locale.getDefault(), "%2d:%02d", minutes, seconds));
        session_text_view.setText(timeLeftFormatted);
    }

    public void updateSessionInterface() {
        if (SessionTimerRunning) {
            session_edit_text.setVisibility(android.view.View.INVISIBLE);
            session_set_button.setVisibility(android.view.View.INVISIBLE);
            session_reset_button.setVisibility(android.view.View.VISIBLE);
            session_start_button.setText("Pause");
        } else {
            session_edit_text.setVisibility(android.view.View.VISIBLE);
            session_set_button.setVisibility(android.view.View.VISIBLE);
            session_reset_button.setVisibility(android.view.View.VISIBLE);
            session_start_button.setText("Start");
        }
    }

Таймер B

dro_set_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(android.view.View view) {
                String DROinput = dro_edit_text.getText().toString();
                if (DROinput.length() == 0) {
                    Toast.makeText(getActivity(), "Fill it in", Toast.LENGTH_SHORT).show();
                    return;
                }
                long millisInput = Long.parseLong(DROinput) * 1000;
                if (millisInput == 0) {
                    Toast.makeText(getActivity(), "Please enter a positive number", Toast.LENGTH_SHORT).show();
                    return;
                }
                setDROTime(millisInput);
                dro_edit_text.setText("");
                imm.hideSoftInputFromWindow(getView().getWindowToken(), 0);
            }
        });

        dro_start_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(android.view.View view) {
                if (DROTimerRunning) {
                    pauseDROTimer();
                } else {
                    startDROTimer();
                }
            }
        });

        dro_reset_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(android.view.View view) {
                if (DROTimerRunning) {
                    resetDROTimer();
                } else {
                    resetDROTimer();
                }
            }
        });
  return View;
    }
public void setDROTime(long milliseconds) {
        DROStartTimeInMillis = milliseconds;
        resetDROTimer();
    }

    public void startDROTimer() {
        DROEndTime = System.currentTimeMillis() + DROTimeLeftInMillis;
        droTimer = new CountDownTimer(DROTimeLeftInMillis, 100) {
            @Override
            public void onTick(long millisUntilFinished) {
                DROTimeLeftInMillis = millisUntilFinished;
                updateDROText();
            }

            @Override
            public void onFinish() {
                ToneGenerator toneGenerator = new ToneGenerator(AudioManager.STREAM_ALARM, 400);
                toneGenerator.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 200);
                DROTimerRunning = false;
                DROTimeLeftInMillis = DROStartTimeInMillis;
                updateDROText();
                updateDROInterface();
                startDROTimer();
            }
        }.start();

        DROTimerRunning = true;
        dro_start_button.setText("Pause");
    }

    public void pauseDROTimer() {
        droTimer.cancel();
        DROTimerRunning = false;
        dro_start_button.setText("Start");
        updateDROText();
    }

    public void resetDROTimer() {
        if (DROTimerRunning) {
            droTimer.cancel();
            DROTimeLeftInMillis = (DROStartTimeInMillis);
            updateDROInterface();
            startDROTimer();
        } else {
            DROTimeLeftInMillis = (DROStartTimeInMillis);
            updateDROText();
            updateDROInterface();
            dro_reset_button.setVisibility(android.view.View.VISIBLE);
            dro_start_button.setVisibility(android.view.View.VISIBLE);
        }
    }

    public void updateDROText() {
        int seconds = (int) (DROTimeLeftInMillis/1000)%60;

        String timeLeftFormatted = String.format(Locale.getDefault(),
                timeLeftFormatted = String.format(Locale.getDefault(), ":%02d", seconds));
        dro_text_view.setText(timeLeftFormatted);
    }

    public void updateDROInterface() {
        if (DROTimerRunning) {
            dro_edit_text.setVisibility(android.view.View.INVISIBLE);
            dro_set_button.setVisibility(android.view.View.INVISIBLE);
            dro_reset_button.setVisibility(android.view.View.VISIBLE);
            dro_start_button.setText("Pause");
        } else {
            dro_edit_text.setVisibility(android.view.View.VISIBLE);
            dro_set_button.setVisibility(android.view.View.VISIBLE);
            dro_reset_button.setVisibility(android.view.View.VISIBLE);
            dro_start_button.setText("Start");
        }
    }
 @Override
    public void onStop() {
        super.onStop();

        SharedPreferences preferences = this.getActivity().getSharedPreferences("prefs", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = preferences.edit();

        editor.putLong("SessionStartTimeInMillis", SessionStartTimeInMillis);
        editor.putLong("DROStartTimeInMillis", DROStartTimeInMillis);
        editor.putLong("MillisLeft", SessionTimeLeftInMillis);
        editor.putLong("DROMillisLeft", DROTimeLeftInMillis);
        editor.putBoolean("TimerRunning", SessionTimerRunning);
        editor.putBoolean("DROTimerRunning", DROTimerRunning);
        editor.putLong("EndTime", SessionEndTime);
        editor.putLong("DROEndTime", DROEndTime);

        if (sessionTimer !=null); {
            sessionTimer.cancel();
        }
    }

    @Override
    public void onStart() {
        super.onStart();

        SharedPreferences preferences = this.getActivity().getSharedPreferences("prefs", Context.MODE_PRIVATE);

        SessionStartTimeInMillis = preferences.getLong("SessionStartTimeInMillis", 0);
        SessionTimeLeftInMillis = preferences.getLong("MillisLeft", SessionTimeLeftInMillis);
        SessionTimerRunning = preferences.getBoolean("TimerRunning", false);

        DROStartTimeInMillis = preferences.getLong("DROStartTimeInMillis", 0);
        DROTimeLeftInMillis = preferences.getLong("DROMillisLeft", DROTimeLeftInMillis);
        DROTimerRunning = preferences.getBoolean("DROTimerRunning", false);

        updateSessionText();
        updateSessionInterface();
        updateDROText();
        updateDROInterface();

        if (SessionTimerRunning) {
            SessionEndTime = preferences.getLong("EndTime", 0);
            SessionTimeLeftInMillis = SessionEndTime - System.currentTimeMillis();

            if (SessionTimeLeftInMillis <0) {
                SessionTimeLeftInMillis = 0;
                SessionTimerRunning = false;
            } else {
                startSessionTimer();
            }
        }

        if (DROTimerRunning) {
            DROEndTime = preferences.getLong("EndTime", 0);
            DROTimeLeftInMillis = DROEndTime - System.currentTimeMillis();

            if (DROTimeLeftInMillis <0) {
                DROTimeLeftInMillis = 0;
                DROTimerRunning = false;
            } else {
                startDROTimer();
            }
        }
    }
}
...