Search code examples
javaandroidcountdown

Countdown Timers running concurrently instead of consecutively


I'm trying to make an app where you can input the length of a session, and the number of sessions then it countdown the length of the session, beep and then start a new countdown automatically if there is still sessions left but at the moment, the app starts all the countdowns at the same time.

So if there was 3 sessions that were each 30 seconds long it reduces the counter by a value of 3 per second from 30 to -60.

What I'm trying to get it to do in this scenario, is start a countdown from 30 to 0, beep and then start the second countdown from 30 to 0 beep and then start a 3rd countdown from 30 to 0.

This is the manActivity.Java

package uk.co.test.fitnesstimer;

import android.content.Context;
import android.media.AudioManager;
import android.media.ToneGenerator;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import static uk.co.test.fitnesstimer.R.id.countdownTimer;
import static uk.co.test.fitnesstimer.R.id.session_length;


public class MainActivity extends AppCompatActivity {
    public int counter;
    public int sessionsLeft;
    Button button;
    TextView textView;
    public int lengthOfActivities = 30;
    public int numOfActivities = 1;
    public int isActive = 0;

    public void increment(View view) {
        lengthOfActivities++;
        display(lengthOfActivities);
    }

    public void decrement(View view) {
        if (lengthOfActivities > 1) {
            lengthOfActivities--;
        }
        display(lengthOfActivities);
    }

    public void incrementNumOfActivities(View view) {
        numOfActivities++;
        displayNum(numOfActivities);
    }

    public void decrementNumOfActivities(View view) {
        if (numOfActivities > 1) {
            numOfActivities--;
        }
        displayNum(numOfActivities);
    }

    private void display(int number) {
        TextView quantityTextView = (TextView) findViewById(R.id.session_length);
        quantityTextView.setText(String.valueOf(number));

    }

    private void displayNum(int number) {
        TextView quantityTextView = (TextView) findViewById(R.id.numOfActivities);
        quantityTextView.setText(String.valueOf(number));

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = (Button) findViewById(R.id.button);
        textView = (TextView) findViewById(countdownTimer);
        button.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v) {
                if (isActive == 0){
                    isActive = 1;
                    sessionsLeft = numOfActivities;
                    counter = lengthOfActivities;
                    while (sessionsLeft > 0) {
                        new CountDownTimer((lengthOfActivities * 1000), 1000){
                            public void onTick(long millisUntilFinished){
                                textView.setText(String.valueOf(counter));
                                //if (counter > 0) {
                                    counter = counter - 1;
                                //}
                            }
                            public  void onFinish(){
                                textView.setText("FINISH!!");
                                ToneGenerator toneGen1 = new ToneGenerator(AudioManager.STREAM_MUSIC, 100);
                                toneGen1.startTone(ToneGenerator.TONE_CDMA_PIP,150);
                                isActive = 0;
                            }
                        }.start();
                        sessionsLeft--;
                    }
                }
                else {
                    Context context = getApplicationContext();
                    CharSequence text = "Timer is running already!";
                    int duration = Toast.LENGTH_SHORT;
                    Toast toast = Toast.makeText(context, text, duration);
                    toast.show();
                }

            }
        });
    }
}

and this is the ActivityMain XML

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp"
    tools:context="uk.co.test.fitnesstimer.MainActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Length Of Sessions:"
        android:textAllCaps="true" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="-"
            android:layout_weight="1"
            android:onClick="decrement" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:id="@+id/session_length"
            android:text="30"
            android:gravity="center"
            android:layout_weight="1" />

        <Button
            android:layout_width="1dp"
            android:layout_height="wrap_content"
            android:text="+"
            android:onClick="increment"
            android:layout_weight="1" />

    </LinearLayout>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Number Of Sessions:"
        android:textAllCaps="true" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="-"
            android:layout_weight="1"
            android:onClick="decrementNumOfActivities" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:id="@+id/numOfActivities"
            android:layout_weight="1"

            android:gravity="center"
            android:text="1" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="+"
            android:layout_weight="1"
            android:onClick="incrementNumOfActivities" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="Start"
            android:id="@+id/button"
            android:onClick="submitOrder"
            android:layout_weight="1" />

     </LinearLayout>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=""
        android:id="@+id/countdownTimer" />

</LinearLayout>

Solution

  • If you want to call your count downs consecutively , you should write a recursive function rather than a while .. which will call itself after each countdown

    Put all the logic that you have written in onClick in a function and make it call itself recursively till all your sessions are completed.

     private void countDown()
    {
        counter = lengthOfActivities;
        if (sessionsLeft > 0) {
            new CountDownTimer((lengthOfActivities * 1000), 1000)
            {
                public void onTick(long millisUntilFinished){
                    textView.setText(String.valueOf(counter));
                    counter = counter - 1;
                }
                public  void onFinish(){
                    textView.setText("FINISH!!");
                    ToneGenerator toneGen1 = new ToneGenerator(AudioManager.STREAM_MUSIC, 100);
                    toneGen1.startTone(ToneGenerator.TONE_CDMA_PIP,150);
                    isActive = 0;
                    sessionsLeft--;
                    countDown();
                }
            }.start();
        }
    }
    

    // in onclick

    if (isActive == 0){
                    isActive = 1;
                    sessionsLeft = numOfActivities;
                    countDown();
                }