Poner un reloj en la barra de título(ActionBar) de los settings de tu aplicación Android

Introducción

Hay ocasiones que nos interesa poner un relog en los settings, por ejemplo cuando tenemos una pantalla en la que se programan unos horários de funcionamiento. Cuando los estas configurando te interesar saber la hora actual para poder ajustar al máximo las configuraciones.

En este artículo lo vamos ha realizar aprovechanbdo el subtítulo del ActionBar, se podría hacer poniendo algo más vistoso, pero eso sería más costoso y lo que buscamos es que sea practico y facil de implementar.

Funcionamiento

Lo que vamos a hacer es poner un timer que llame a un método cada segundo.

El método compondrá la cadena de texto a poner en el subtitulo y lanzara un evento para que lo campure el handrereceiver y actualice dicho subtítulo. El método no puede modificar directamente el subtítulo por que un hilo de segundo plano no tiene acceso a los objetos gráficos del primer plano.

Como podéis ver es sencillo.

Creación del Timer

Vamos a definir un atributo para que el timer séa accesible desde cualquier método y así poder eliminarlo cuando sea necesario.

También vamos a crear un atributo para tener la referencia del ActionBar y no tener que solicitarla cada segundo, esto consumiría muchos recursos y proceso.

	private Timer TimerReloj = null; // timer que se utiliza para actualizar el reloj
	private ActionBar actionBar = null; // la utilizo para actualizar el subtitulo con el reloj
	private static int SET_HORA = 1150;

Tenemos que modificar el método “onCreate” u “onPostCreate” para añadir la inicialización del timer y la asignación del actionBar a nuestro atributo.

	actionBar = getActionBar();
        // ponemos un reloj en la actionBar
        TimerReloj  = new Timer();
        TimerReloj.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() 
            {
        	    lanzaEsperaRefrescoReloj();
            }
        }, 0, 1000); // cada 1 segundos
	    lanzaEsperaRefrescoReloj();

El método lanzaEsperaRefrescoReloj()

Este método como indicaba al principio se encarga de calcular la hora actual para componer una cadena de carácteres y lanza en handler para que se actualice el subtítulo.

	/**
	 * Se encarga de refrescar la hora en la actionBar
	 */
	public void lanzaEsperaRefrescoReloj()
	{
		try {
			// Compone la cadena con la hora actual.
			Calendar cal = Calendar.getInstance();
			cal.setTime(new Date());
			String sHora = Integer.toString(cal.get(Calendar.HOUR_OF_DAY));
			if(sHora.length() [b] 1)
				sHora = "0" + sHora;

			String sMinuto = Integer.toString(cal.get(Calendar.MINUTE));
			if(sMinuto.length() [b] 1)
				sMinuto = "0" + sMinuto;

			String sSegundo = Integer.toString(cal.get(Calendar.SECOND));
			if(sSegundo.length() [b] 1)
				sSegundo = "0" + sSegundo;

			// Lanza el handler
			Intent i = new Intent(Intent.ACTION_VIEW);            
			i.putExtra("accion", SET_HORA);
			i.putExtra("sHora", sHora + ":" + sMinuto + ":" + sSegundo);
			sendOrderedBroadcast(i, null);
		} catch(Exception e)
		{
			;
		}
	}

Creación y destrucción del receiver

El receiver es el encargado de actualizar el subtítulo con lo que se le indica. El primer paso es añadir al método “onCreate” o el método “onPostCreate” la creación del receiver antes de crear el timer. la línea a poner sería.

	// registramos el receiver para que se puedan comunicar la parte servidora y el cliente y recibir la actualización de la hora 
        registerReceiver(receiver, new IntentFilter(Intent.ACTION_VIEW));

El receiver se tiene que destruri y crear cada vez que tengamos un pause o un resume, también se tiene que destruir cuando tenemos un “onDestroy”.
En el siguiente código podemos ver estos métodos.

	/**
	 * Lo sobreescribo para matar el hilo del reloj y liberar el receiver 
	 */
	protected void onDestroy(){
		super.onDestroy();

		// eliminamos el timer
		if(TimerReloj != null)
		{
			TimerReloj.cancel();
			TimerReloj.purge();
			TimerReloj = null;
		}

		try { unregisterReceiver(receiver); } catch(Exception e) { ; }
	}

	protected void onResume() {
		super.onResume();

		// si estaba arrancado lo matamos para empezar de cero.
		if(TimerReloj != null)
		{
			TimerReloj.cancel();
			TimerReloj.purge();
			TimerReloj = null;

			// liberamos el receiver
			try { unregisterReceiver(receiver); } catch(Exception e) { ; }
		}

		// registramos el receiver para que se puedan comunicar la parte servidora y el cliente y recibir la actualización de la hora 
		registerReceiver(receiver, new IntentFilter(Intent.ACTION_VIEW));
		// ponemos un reloj en la actionBar
		TimerReloj  = new Timer();
		TimerReloj.scheduleAtFixedRate(new TimerTask() {
		    @Override
		    public void run() 
		    {
			    lanzaEsperaRefrescoReloj();
		    }
		}, 0, 1000); // cada 1 segundos
		lanzaEsperaRefrescoReloj();
	}

	/**
	 * Sobreescribimos onResume para que se la lista deje de hacer cosas
	 */
	protected void onPause() {
		super.onPause();
		if (getListAdapter() instanceof CDIPrefsHeaderAdapter)
			((CDIPrefsHeaderAdapter) getListAdapter()).pause();

		// eliminamos el timer
		if(TimerReloj != null)
		{
			TimerReloj.cancel();
			TimerReloj.purge();
			TimerReloj = null;
		}

		// liberamos el receiver
		try { unregisterReceiver(receiver); } catch(Exception e) { ; }
	}

A continuación tenemos el receiver que recoge el parámetro extra “sHora” y lo utiliza para actualizar la hora.

para diferenciar un evento de otro, se pone el extra “accion” con el código que nos interesa que en este caso es el valor de SET_HORA.

	/**
	 * Receiber que se utiliza para recibir las actualizaciones de la hora
	 */
	private BroadcastReceiver receiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			try {
			    if(intent.getIntExtra("accion", 0) [b] SET_HORA)
		    		    actionBar.setSubtitle(intent.getStringExtra("sHora"));
			}catch(Exception e){
		    		;
			}
		}
	};

Añadir comentario

Rellene el siguiente formulario para añadir sus propios comentarios

Datos de Usuario





Añada su comentario