App – Crear un CountDownTimer

Hoy vamos a ver como crear una aplicación bastante simple, una aplicación que hará de cuenta atrás, aunque el hecho de tener un Android ya trae este tipo de herramientas consigo, pero igualmente vamos a crear una aplicación para ir entendiendo algo más sobre el trabajo interno de las aplicaciones.


  • Problema

    Queremos un contador de cuenta atrás simple, el programa contará desde un número dado de segundos hasta que se llegue a 0

  • Solución:

    Android viene con una clase ya construida para la construcción de contadores de cuenta atrás. Es fácil de usar, es eficiente, y funciona

  • Discursión:

    Los pasos que seguiremos para crear la aplicación son los siguientes:

    1. Crearemos una subclase de CountDownTimer. El constructor de la clase coge 2 argumentos

      CountDownTimer (long millisInFuture, long countDownInterval)

      El primer parámetro es el número de milisegundos desde ahora hasta que el intervalo debería realizarse; en este punto el método onFinish() de la subclase será llamado. El segundo parámetro es la frecuencia en milisegundos sobre cuando quieres que se notifique que el tiempo está todavía corriendo, lo típico para actualizar y monitorizar el progreso o comunicarsecon el usuario. El método onTick() de la subclase será llamado con el paso de los milisegundos

    2. Sustituir los métodos onClick() y onFinish()
    3. Instanciar una nueva instancia de nuestra clase en la Actividad
    4. Llamar al método start() cuando se cree la nueva instancia

Visto la especificación y lo que haremos, podemos ponernos manos a la obra con la aplicación.


  1. Lo primero es crear el Android Application Project, donde pondremos el nombre de la aplicación, el nombre del paquete, y los la API mínima y máxima que usaremos:
  2. Una vez creado nuestro proyecto de Android, empezaremos definiendo la GUI o Interfaz Gráfica de Usuario
    	<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    	<Button
    	    android:id="@+id/button1"
    	    android:text="@string/btnStart"
    	    android:layout_width="fill_parent"
    	    android:layout_height="wrap_content" />
    	<TableLayout 
    	    android:padding="10dip"
    	    android:layout_gravity="center"
    	    android:layout_width="fill_parent"
    	    android:layout_height="wrap_content">
    	    <TableRow>
    	        <TextView
    	            android:id="@+id/timer"
    	            android:text="@string/tvTimer"
    	            android:paddingRight="10dip"
    	            android:layout_width="wrap_content"
    	            android:layout_height="wrap_content" />
    	       
    	        <TextView
    	            android:id="@+id/timeElapsed"
    	            android:text="@string/tvElapsed"
    	            android:paddingRight="10dip"
    	            android:layout_width="wrap_content"
    	            android:layout_height="wrap_content" />
    	       
    	    </TableRow>
    	</TableLayout>
    	    
    </LinearLayout>
    
    	

    Esto hará que tenga un aspecto como esto:

  3. Ahora comenzamos a construir la Actividad:
            package com.sekthdroid.mycountdowntimer;
    
    import android.os.Bundle;
    import android.os.CountDownTimer;
    import android.view.View;
    import android.widget.TextView;
    import android.widget.Button;
    import android.view.View.OnClickListener;
    import android.app.Activity;
    import android.view.Menu;
    
    public class MainActivity extends Activity implements OnClickListener {
    
    	private MiCountDownTimer countDownTimer;
    	private long timeElapsed;
    	private boolean timerHasStarted = false;
    	private Button startB;
    	private TextView text;
    	private TextView timeElapsedView;
    	private final long startTime = 50*1000;
    	private final long interval = 1*1000;
    	
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            //Referenciamos los Button y TextView con los creados en el XML
            startB = (Button) this.findViewById(R.id.button1);
            startB.setOnClickListener(this);
            
            text = (TextView)this.findViewById(R.id.timer);
            timeElapsedView = (TextView)this.findViewById(R.id.timeElapsed);
            
            //Instanciamos nuestra clase modificada
            countDownTimer = new MiCountDownTimer(startTime, interval);
            
            text.setText(text.getText() + String.valueOf(startTime));
            
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.activity_main, menu);
            return true;
        }
    
    	@Override
    	public void onClick(View v) {
    		// TODO Auto-generated method stub
    		
    		if (!timerHasStarted){
    			countDownTimer.start();
    			timerHasStarted = true;
    			startB.setText("Start");
    		}else {
    			countDownTimer.cancel();
    			timerHasStarted = false;
    			startB.setText("Reset");
    		}
    	}
    	
    	//Nuestra clase CountDownTimer modificada
    	public class MiCountDownTimer extends CountDownTimer {
    
    		public MiCountDownTimer(long starTime, long interval) {
    			super(starTime, interval);
    			// TODO Auto-generated constructor stub
    		}
    
    		@Override
    		public void onFinish() {
    			// TODO Auto-generated method stub
    			
    			text.setText("Time's Up!");
    			timeElapsedView.setText("Time Elapsed: " + String.valueOf(startTime));
    			
    		}
    
    		@Override
    		public void onTick(long millisUntilFinished) {
    			// TODO Auto-generated method stub
    
    			text.setText("Time remain:" +millisUntilFinished);
    			timeElapsed = startTime - millisUntilFinished;
    			timeElapsedView.setText("Time Elapsed: " + String.valueOf(timeElapsed));
    			}
    
    	}
    
    }
    	

    Como vemos, la subclase que hemos creado nueva hereda los métodos onFinish() y onTick() que son los que modificaremos. Como vemos, el método OnFinish(), cuando se le llama, asignará al TextView que llamamos text un nuevo texto que será “Time’s Up!” y luego asigna tambien otro texto al TextView que llamamos con anterioridad para que muestre lo que ha tardado la cuenta atrás. En el método onTick(long millisUntilFinished) se modifica el texto del TextView que anteriormente llamamos text para que muestre el tiempo en milisegundos que queda para que termine la cuenta atrás, a continuación, la variable timeElapsed guarda el tiempo que ha transcurrido restandole al tiempo inicial el tiempo que queda hasta finalizar, y luego se cambia el texto del TextView llamado timeElapsedView.

  4. Ahora ya podemos transferirla a nuestro teléfono, y probarla, ejecutarla, funcionará, pero es bastante básica, no nos preocuparemos, podremos ir mejorandola a medida que vayamos viendo mas cosas, para hacerla un poco mejor.
    El aspecto final sería este:

    Cualquier aporte o corrección es bienvenido.

    Saludos!!!