En este video te explicamos en detalle todo el proceso para publicar una Aplicación Android…

Proyecto AlarmManager
En este tutorial vamos a desarrollar una sencilla aplicación Android, que nos servirá como ejercicio práctico para ver la implementación de la clase AlarmManager. En ella utilizaremos esta clase, y la clase Thread, para programar tareas en segundo plano.
Puedes descargar todo el código de este proyecto al final de este tutorial
La estructura de la aplicación estará formada por:
- Una clase MainActivity que heredará de Activity, donde se definirán los elementos visuales y eventos encargados de realizar las diferentes llamadas. Estas ejecutarán tareas en background, y programarán el lanzamiento de dichas tareas, de manera repetida, en intervalos de tiempo elegidos por el usuario, o en una hora determinada.
- También definiremos una clase llamada PlanificarTareas, que heredará de la clase base BroadcastReceiver, encargada de recibir los diferentes intents lanzados por la tarea en segundo plano.
A nivel de Layout será necesario añadir los siguientes elementos (sólo se mencionarán los elementos que intervienen en la planificación de tareas):
- Dos componentes de tipo ImageButton encargados de programar la repetición de la alarma en un intervalo de tiempo indicado por el usuario, o programar la ejecución de la tarea a una hora determinada.
- Un componente de tipo TimePicker para programar la tarea a una hora específica.
- Un componente de tipo EditText (tipo de entrada «número») para indicar cada cuántos segundos queremos que se repita la tarea en segundo plano
- Dos componentes de tipo TextView para mostrar la hora programada o el intervalo de tiempo, en segundos, para la repetición de la tarea, además de mostrar el estado de progreso de la misma.
- Además será necesario definir un componente de tipo ProgressBar para mostrar el progreso de la tarea lanzada, utilizando la clase Thread en conjunto con la clase Handler (esta última estará encargada de comunicar y refrescar la UIThread o hilo principal con los cambios).
TareasSegundoPlano/src/com.academiaandroid.tareassegundoplano/MainActivity.java
En primer lugar se enlazan los componentes con los recursos definidos a nivel de layout, dónde podemos destacar el uso del componente ProgressBar para mostrar una tarea en ejecución, y el componente TimePicker y EditText, para programar la ejecución de las tareas.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
[...] //Se definen los elementos necesarios para la lógica de manejo de la aplicación. private TextView tvTipoTarea; private ImageButton btnProgramarTarea; private ImageButton btnProgramarTareaRepetitiva; private TimePicker timePickerTarea; ProgressBar prgssTarea; private TextView tvEstadoProgreso; private EditText edSegundos; AlarmManager planificarAlarma; private static MainActivity mainactivity; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mainactivity = this; timePickerTarea = (TimePicker)findViewById(R.id.timePickerTarea); btnProgramarTarea = (ImageButton)findViewById(R.id.btnAlarmManager); btnProgramarTareaRepetitiva = (ImageButton)findViewById(R.id.btnProgramarTareaRepetitiva); edSegundos = (EditText)findViewById(R.id.edSegundos); |
Posteriormente se define el evento encargado de controlar si el botón con la imagen del reloj ha sido pulsado, para la programación de una tarea, con la hora indicada por el usuario en el componente TimePicker:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
//Evento que caza el cambio de estado del botón con la imagen del reloj, estableciendo la hora de arranque en la hora actual, instanciando la clase Calendar, //y programando la tarea para ser ejecutada a la hora indicada por el usuario. btnProgramarTarea.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { try{ Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(System.currentTimeMillis()); cal.set(Calendar.HOUR_OF_DAY,timePickerTarea.getCurrentHour()); cal.set(Calendar.MINUTE,timePickerTarea.getCurrentMinute()); cal.set (Calendar.SECOND, 0); int hora = timePickerTarea.getCurrentHour(); int minutos = timePickerTarea.getCurrentMinute(); String hora_programada = newStringBuilder().append(hora).append(":0").append(minutos) + " hrs"; if(minutos < 10) { tvTipoTarea.setText("Tarea programada a las --> " + hora_programada); }else { hora_programada = newStringBuilder().append(hora).append(":").append(minutos) + " hrs"; tvTipoTarea.setText("Tarea programada a las --> " + hora_programada); } Toast.makeText(getApplicationContext(), "Tarea programada a las " + hora_programada.toString(), Toast.LENGTH_SHORT).show(); planificarAlarma = (AlarmManager)getSystemService(ALARM_SERVICE); Intent intent = new Intent(getApplicationContext(), PlanificarTareas.class); PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, 0); planificarAlarma.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pi); }catch(Exception ex) { System.out.println("Error al programar hora de tarea: " + ex.getMessage()); } } }); |
Otro de los eventos a comentar, sería el lanzado por el botón con la imagen de dos flechas, a modo de recarga, indicando en el componente EditText, el tiempo en segundo que deseamos como intervalo de repetición de la alarma programada:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
//Evento que caza el cambio de estado del botón con la imagen de dos flechas a modo de recarga, estableciendo como parámetro de repetición de //la alarma, los segundos introducidos en el componente EditText. btnProgramarTareaRepetitiva.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if(edSegundos.getText().toString().equals("")) { Toast.makeText(getApplicationContext(), "Debe indicar el intervalo de tiempo para la repetición de las tareas.", Toast.LENGTH_LONG).show(); }else { String segundos = edSegundos.getText().toString(); tvTipoTarea.setText("Repetición de tarea cada " + segundos + " sg."); Toast.makeText(getApplicationContext(), "Tarea programada cada " + segundos + " sg.", Toast.LENGTH_SHORT).show(); planificarAlarma = (AlarmManager)getSystemService(ALARM_SERVICE); Intent intent = new Intent(getApplicationContext(), PlanificarTareas.class); PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, 0); long tiempo_repeticion = Long.parseLong(segundos); planificarAlarma.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 60000, tiempo_repeticion*1000, pi); } } }); [...] |
En primer lugar crearemos un clase que herede de BroadcastReceiver:
public class PlanificarTareas extends BroadcastReceiver{Posteriormente se sobrescribirá el método OnReceive desde dónde se invocará al método que ejecute la tarea en segundo plano:
1 2 3 4 5 6 7 8 9 |
//Método que será invocado, cuando el BroadcastReceiver esté recibiendo un intent, en el que lanzaremos la tarea definida en la Activity principal. //En este caso lanzaremos una tarea con las clases Thread y Handler, a través del método runThread(). @Override public void onReceive(Context context, Intent intent) { MainActivity.getInstance().runThread(); Toast.makeText(context, "Tarea programada en curso", Toast.LENGTH_LONG).show(); } [...] |
Como podemos comprobar en la imagen siguiente, se ha definido un TableLayout, con varios tableRow, encargados de mostrar de manera ordenada los diferentes componentes que comentamos a continuación:
- El componente TimePicker, permitirá programar una tarea a una hora indicada.
- Los diferentes componentes de tipo ImageButton permiten programar una tarea una hora concreta, o su repetición en un intervalo de tiempo indicado.
- El componente ProgressBar es el encargado de mostrar el progreso de la tarea, actualizando el porcentaje de progreso en el componente TextView (‘Sin Progreso’).
- Por último, se define un componente EditText, que recogerá el valor en segundos, del intervalo de repetición entre tarea y tarea.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
[...] <TableLayout android:layout_width="wrap_content" android:layout_height="wrap_content" > <TableRow android:id="@+id/tableRow9" android:layout_width="wrap_content" android:layout_height="wrap_content" > <TimePicker android:id="@+id/timePickerTarea" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <ImageButton android:id="@+id/btnAlarmManager" style="?android:attr/buttonStyleSmall" android:layout_width="15dp" android:layout_height="wrap_content" android:src="@drawable/tareas_programadas" /> </TableRow> <TableRow android:id="@+id/tableRow10" android:layout_width="wrap_content" android:layout_height="wrap_content" > <EditText android:id="@+id/edSegundos" android:layout_width="wrap_content" android:layout_height="wrap_content" android:ems="10" android:hint="Segundos entre tareas" android:inputType="number" /> <ImageButton android:id="@+id/btnProgramarTareaRepetitiva" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/tareas_repetitivas" /> </TableRow> </TableLayout> [...] |
Programación de tareas en segundo plano con las clases Thread, Handler y AlarmManager.
Como se puede comprobar en la imagen, se programa una tarea a las 2:49 PM y se pulsa el botón con la imagen del reloj. En el reloj del dispositivo se puede apreciar que dicha alarma funciona correctamente:
Repetición de tareas en segundo plano con las clases Thread, Handler y AlarmManager.
En la siguiente imagen se aprecia cómo se ha establecido un tiempo de 35 segundos como intervalo de repetición entre tarea y tarea, pulsando el botón de recarga:
Descarga
Pincha aquí para descargar el código de este proyecto
DownloadEsta entrada tiene 5 comentarios
Los comentarios están cerrados.
muy buen block de informacion
busco formación en android
Hola Roberto,
no sabemos si entendemos bien tu comentario dado que en esta web tienes gran cantidad de contenidos formativos sobre programación Android. Aquí tienes las temáticas que hemos tratado hasta ahora: http://academiaandroid.com/tematicas-series-de-publicaciones/
También tienes nuestros cursos online, que abarcan desde una iniciación (aprender los fundamentos de programar en Java y Programación Orientada a Objetos que es básico antes de iniciarse en Android y que continuaría con nuestro curso para aprender a desarrollar Apps para Android) a formación más especializados, por ejemplo en bases de datos para Android. En este enlace tienes los cursos disponibles: http://academiaandroid.com/cursos-formacion/
Por supuesto si buscas en Internet, encontrarás más documentación sobre Java y Android. Depende de lo quieras ya puedes elegir.
Saludos
Me ayudo mucho este blog, ahora lo que estoy buscando es que me salga una pantalla aun que el telefono este bloqueado, es decir, algo asi como cuando programas una alarma en el relog y cuando llega la hora comienza a sonar y aunq ue el telefono este bloquedo te manda la pantalla que te permite cancelar la alarma
gracias por su ayuda
Saludos
Hola Eduardo, el trabajar en segundo plano y no bloquear el Main Thread se realiza con otras clases.
Es algo que todavía no hemos tocado en estos tutoriales, pero no lo anotamos para intentar desarrollarlo más adelante. Puedes probar viendo: http://developer.android.com/intl/es/reference/android/os/PowerManager.html
Saludos