1
votes

I am trying to implement a 24 hour countdown timer with three separate textviews one holds hours, one holds minutes, and one holds seconds.

enter image description here

When the start time button is pushed I want the timer to count down.

I have done a lot of research on this and tried to implement many examples, learn from the documentations and modify it to my liking, but I couldn't produce a solid solution.

Countdown timer in HH:MM:SS format in Android

Display timer in textview contain days, hours, minutes and seconds in android

The problem is that for the countdown timer in android it is usually implemented with just one textview treated as a long string with the time and then it counts down from there. I am not sure how I would approach the 24 hour countdown timer in my case since I have three separate textviews.

I'm surprised I couldn't find much about this problem.

I.E.

For example here I have a countdown timer, but this is only using one textview. How would I make something that takes in consideration my three separate textviews for hours, minutes, and seconds and countsdown accordingly.

    Button buttonStartTime;                 // clicking this button will start time count down 
    TextView textViewShowTime;              // will show the time 
    CountDownTimer countDownTimer;          // built in android class CountDownTimer
    long totalTimeCountInMilliseconds;      // total count down time in milliseconds 
    long timeBlinkInMilliseconds;           // start time of start blinking 
    boolean blink;                          // controls the blinking .. on and off 

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        getReferenceOfViews ();                         // get all views 
        setActionListeners ();                          // set action listerns 

        totalTimeCountInMilliseconds = 60 * 1000;      // time count for 3 minutes = 180 seconds
        timeBlinkInMilliseconds = 30 * 1000;            // blink starts at 1 minutes = 60 seconds
    }

    private void setActionListeners() {

        buttonStartTime.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                textViewShowTime.setTextAppearance(getApplicationContext(), R.style.normalText);

                countDownTimer = new CountDownTimer(totalTimeCountInMilliseconds, 500) {
                    // 500 means, onTick function will be called at every 500 milliseconds 

                    @Override
                    public void onTick(long leftTimeInMilliseconds) {
                        long seconds = leftTimeInMilliseconds / 1000;

                        if ( leftTimeInMilliseconds < timeBlinkInMilliseconds ) {
                            textViewShowTime.setTextAppearance(getApplicationContext(), R.style.blinkText);
                            // change the style of the textview .. giving a red alert style 

                            if ( blink ) {
                                textViewShowTime.setVisibility(View.VISIBLE);
                                // if blink is true, textview will be visible
                            } else {
                                textViewShowTime.setVisibility(View.INVISIBLE);
                            }

                            blink = !blink;         // toggle the value of blink
                        }

                        textViewShowTime.setText(String.format("%02d", seconds / 60) + ":" + String.format("%02d", seconds % 60));
                        // format the textview to show the easily readable format
                    }

                    @Override
                    public void onFinish() {
                        // this function will be called when the timecount is finished
                        textViewShowTime.setText("Time up!");
                        textViewShowTime.setVisibility(View.VISIBLE);
                    }

                }.start();

            }
        });
    }

    private void getReferenceOfViews() {

        buttonStartTime = (Button) findViewById(R.id.btnStartTime);
        textViewShowTime = (TextView) findViewById(R.id.tvTimeCount);
    }
}

Edit: Right now I have this:

private void setActionListeners() {

        start_timer.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

               // textViewShowTime.setTextAppearance(getApplicationContext(), R.style.normalText);

                countDownTimer = new CountDownTimer(totalTimeCountInMilliseconds, 500) {
                    // 500 means, onTick function will be called at every 500 milliseconds

                    @Override
                    public void onTick(long leftTimeInMilliseconds) {
                        int seconds = leftTimeInMilliseconds / 1000 % 60;
                        int minutes = leftTimeInMilliseconds / 60000 % 60;
                        int hours = leftTimeInMilliseconds / 3600000;




                        if ( leftTimeInMilliseconds < timeBlinkInMilliseconds ) {
                           // textViewShowTime.setTextAppearance(getApplicationContext(), R.style.blinkText);
                            // change the style of the textview .. giving a red alert style

                            if ( blink ) {
                                number_text.setVisibility(View.VISIBLE);
                                minute_text.setVisibility(View.VISIBLE);
                                second_text.setVisibility(View.VISIBLE);


                                // if blink is true, textview will be visible
                            } else {
                                number_text.setVisibility(View.INVISIBLE);
                                minute_text.setVisibility(View.INVISIBLE);
                                second_text.setVisibility(View.INVISIBLE);


                            }

                            blink = !blink;         // toggle the value of blink
                        }

                        number_text = String.format("%02d", seconds % 60);
                        minute_text = String.format("%02d", seconds / 60);
                        second_text = String.format("%02d", seconds / 3600);                        // format the textview to show the easily readable format
                    }

                    @Override
                    public void onFinish() {
                        // this function will be called when the timecount is finished
                        //textViewShowTime.setText("Time up!");
                        //textViewShowTime.setVisibility(View.VISIBLE);
                    }

                }.start();

            }
        });
    }

    private void getReferenceOfViews() {

        start_timer = (Button) findViewById(R.id.start_button);
        number_text = (TextView) findViewById(R.id.hour_progress_number);
        minute_text = (TextView) findViewById(R.id.minute_progress_number);
        second_text = (TextView) findViewById(R.id.second_progress_number);


    }

I am getting these errors.

enter image description here

enter image description here

3

3 Answers

0
votes

Inside your onTick() instead of:

textViewShowTime.setText(String.format("%02d", seconds / 60) + ":" + String.format("%02d", seconds % 60));

do:

textViewSeconds.setText(String.format("%02d", seconds % 60));
textViewMinutes.setText(String.format("%02d", seconds / 60));
textViewHours.setText(String.format("%02d", seconds / 3600));
0
votes

I know it's too late to reply to this question but I have done it now and It may help someone by not spending hours like mine.

It is only coded for 24 hours countdown.

   long startTime = System.currentTimeMillis();

   //adding 24 hours milliseconds with current time of milliseconds to make it 24 hours milliseconds.
   milliseconds = System.currentTimeMillis() + 86400000; // 24 hours = 86400000 milliseconds 

    CountDownTimer cdt = new CountDownTimer(milliseconds,1000) {
    @Override
    public void onTick(long millisUntilFinished) {

    startTime =startTime -1;
    Long serverUptimeSeconds =
            (millisUntilFinished - startTime ) / 1000;

    // now you repalce txtViewHours,  txtViewMinutes, txtViewSeconds by your textView.      

    String hoursLeft = String.format("%d", (serverUptimeSeconds % 86400) / 3600);
    txtViewHours.setText(hoursLeft);
    Log.d("hoursLeft",hoursLeft);

    String minutesLeft = String.format("%d", ((serverUptimeSeconds % 86400) % 3600) / 60);
    txtViewMinutes.setText(minutesLeft);
    Log.d("minutesLeft",minutesLeft);

    String secondsLeft = String.format("%d", ((serverUptimeSeconds % 86400) % 3600) % 60);
    txtViewSecond.setText(secondsLeft);
    Log.d("secondsLeft",secondsLeft);


    }

    @Override
    public void onFinish() {
        Log.i(TAG, "Timer finished");
    }
};

cdt.start();
-1
votes

To display hours, minutes, and seconds separately, you'll have to use the modulus operator and multiplication to parse out the needed info.

Since onTick gives you the countdown time remaining in milliseconds, and one second is 1000 ms, we can divide the total ms left by 1000. This gives us the total number of seconds left. However, since we only want to display the number of seconds left in the current minute, we can take the number of seconds left mod 60. Altogether, this would look like:

int secs = leftTimeInMilliseconds / 1000 % 60;

The process for minutes and hours is pretty similar. There are 60,000 ms in a minute and 60 minutes in an hour, so

int mins = leftTimeInMilliseconds / 60000 % 60;

Then for hours, there are 3,600,000 ms in an hour:

int hours = leftTimeInMilliseconds / 3600000;

Then just set the corresponding textviews to display these numbers inside your onTick method.