En este video te explicamos en detalle todo el proceso para publicar una Aplicación Android…
Notificaciones en Android 5 Lollipop: App ejemplo
4.
Notificaciones en Android 5 Lollipop: App ejemplo
En este apartado, desarrollaremos un proyecto denominado «NotificacionesAndroidLollipop«, en el que se mostrarán las diferentes novedades del sistema de notificaciones que implementa la versión de Android 5.0 Lollipop.
En esta aplicación Android ejemplo, se mostrará un sistema que simulará el envío de notificaciones de email recibido y llamada perdida, controlando la visualización de una notificación heads-up o también denominada flotante, durante el uso de cualquier otra aplicación del dispositivo. También se mostrará como dichas notificaciones podrán visualizarse desde la pantalla de bloqueo (al desbloquear se mostrará el resto de información de la notificación), pudiendo configurar el grado de privacidad de dichas notificaciones. Con este proyecto se pretenden mostrar las novedades que implementa Android 5.0 Lollipop en lo que concierne al sistema de notificaciones.
Pantallas de la Aplicación Android
Si pinchas en las siguientes miniaturas, podrás ver las diferentes pantallas de la Aplicación Android:
- 1ª: pantalla ‘Splash’
- 2ª-4ª: Notificaciones de email
- 5ª-7ª: Notificaciones llamadas
- 8ª: pantalla de bloqueo
- 9ª: notificación flotante
Elementos del Proyecto Android
Se comenzará en primer lugar por enumerar los elementos necesarios para el desarrollo del proyecto denominado «NotificacionesAndroidLollipop»:
- Clase SplashScreen, que herede de la clase base Activity, encargada de lanzar una pantalla de presentación al iniciar la aplicación, proporcionando una mayor inmersión del usuario en la aplicación.
- Clase MainActivity, que herede de la clase base Activity, donde se implementa la lógica de creación de notificaciones a partir de la clase NotificationManager, además de establecer las propiedades necesarias para que las notificaciones recibidas puedan visualizarse tanto en la pantalla de bloqueo como de manera flotante durante el uso de cualquier aplicación del dispositivo.
- Clase GestionEmail, que herede de la clase base Activity, encargada de mostrar el resto de información del email recibido al seleccionar la notificación en la barra de estado.
- Clase GestionLlamadas, que herede de la clase base Activity, encargada de mostrar el resto de información de la llamada perdida recibida al seleccionar la notificación en la barra de estado.
- Layout
activity_splash_screen.xml
, formado por una componente de tipo ImageView, que mostrará el logotipo de la aplicación. - Layout
activity_main.xml
, formado por tres componentes de tipo EditText para introducir los datos que mostrarán las notificaciones, además de tres componentes de tipo Button, encargados de lanzar los eventos de creación de una notificación de email recibido, llamada perdida y cancelación de notificaciones pendientes. Además se define un componente de tipo TextView que mostrará la versión de máquina virtual, para comprobar la compatibilidad de la aplicación con ART. - Layouts
activity_gestion_llamadas
yactivity_gestion_email
, formados ambos por dos componentes de tipo TextView, uno de ellos de tipo multilínea (más concretamente el encargado de mostrar el asunto del email recibido), y un componente de tipo ImageButton, para volver a la pantalla inicial. - Repositorio de iconos y recursos para desarrolladores que proporciona Google con nuevos diseños y refinamiento de componentes que puedes ver en esta página o descargar desde: material-design.storage.googleapis.com/publish/v2/ materialext_publish /0B08MbvYZK1iNUzJ4c1VXWDYzbTA/material-design-icons-1.0.1.zip
Estructura del proyecto
Documentación código fuente
Como siempre, como usuario Premium puedes descargar todo el código de este proyecto al fnal de este tutorial
NotificacionesAndroidLollipop\app\src\main\java\com\academiaandroid\notificacionesandroidlollipop\MainActivity.java
- Se define la clase
MainActivity
, que hereda de la clase baseActivity
, donde se implementan todas las tareas de creación de notificaciones:public class MainActivity extends Activity { - Posteriormente, se declara una variable para la clase
TextView
, además de dos variables de la claseTimerTask
, que permitirán lanzar una determinada tarea pasado un periodo de tiempo establecido:
1234567891011121314151617181920212223[...]private TextView tvVersionVM;TimerTask tareaEmail, tareaLlamada;/*Variable que inicializa el tiempo de retraso para lanzar la tarea de recibir una notificación.*/private static final long INICIAR_ACCION = 10000;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);setContentView(R.layout.activity_main);[...]/*Se enlaza la variable con su componente definido a nivel de layout.*/tvVersionVM = (TextView)findViewById(R.id.tvVersionVM);/*Se invoca al método setText(), que recibirá el valor de la versión de la máquina virtualimplementada.*/tvVersionVM.setText( " " + System.getProperty("java.vm.version"));[...] - A continuación, se inicializan dos objetos de la clase
TimerTask
, donde se establece la lógica de creación de las notificaciones dentro del métodorun()
:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990tareaEmail = new TimerTask() {@Overridepublic void run() {datos_horario = Calendar.getInstance();request = datos_horario.get(Calendar.SECOND);String email = edEmail.getText().toString();String asunto_email = edAsuntoEmail.getText().toString();Intent intentEmail = new Intent(getApplicationContext(),GestionEmail.class);intentEmail.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);intentEmail.putExtra("tipoEmail", "Enviado por: " + email);intentEmail.putExtra("datosEmail", "Asunto del email: " + asunto_email);PendingIntent pIntentEmail = PendingIntent.getActivity(getApplicationContext(), request, intentEmail, 0);NotificationCompat.Builder ntfBuilder = new NotificationCompat.Builder(getApplicationContext()).setContentTitle("Email recibido de: " + email).setSmallIcon(R.drawable.correo_entrante).setTicker("Email recibido")//Método que permite controlar la visibilidad de la información contenida en las notificaciones//que se mostrarán en la pantalla de bloqueo del dispositivo. Se pasa como parámetro un valor entero con la constante//VISIBILITY_PUBLIC, que posibilita la visualización completa de los datos de la notificación..setVisibility(NotificationCompat.VISIBILITY_PUBLIC).setCategory(NotificationCompat.CATEGORY_EMAIL)//Método para establecer el color del círculo situado detrás de la imagen de la notificación,//para controlar una visualización correcta del icono con el nuevo estilo material design. Recibe como parámetro//un valor entero con el sistema de colores argb..setColor(Color.LTGRAY).addPerson(ContactsContract.Contacts._ID)//Este método permite lanzar un intent en lugar de publicar la notificación en la barra de estado,//mostrándola en una ventana flotante o también denominada notificación heads-up. Recibe entre sus parámetros el//intent a lanzar, y un valor booleano con el grado de prioridad, que si se establece en true, siempre//será enviado incluso si se han suprimido las notificaciones..setFullScreenIntent(pIntentEmail,true).addAction(R.drawable.correo_entrante, "Email: " + edEmail.getText().toString() + " Asunto: " + asunto_email, pIntentEmail);NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);notificationManager.notify(NOTIFICACION_ID, ntfBuilder.build());Notification ntf = ntfBuilder.build();ntf.flags |= Notification.DEFAULT_LIGHTS | Notification.FLAG_AUTO_CANCEL;}};tareaLlamada = new TimerTask() {@Overridepublic void run() {datos_horario = Calendar.getInstance();request = datos_horario.get(Calendar.SECOND);String hora_llamada_perdida = datos_horario.get(Calendar.HOUR_OF_DAY) + ":" + datos_horario.get(Calendar.MINUTE);String numero_llamada = edTelefono.getText().toString();if(datos_horario.get(Calendar.MINUTE) < 10){hora_llamada_perdida = datos_horario.get(Calendar.HOUR_OF_DAY) + ":0" + datos_horario.get(Calendar.MINUTE);}else{hora_llamada_perdida = datos_horario.get(Calendar.HOUR_OF_DAY) + ":" + datos_horario.get(Calendar.MINUTE);}Intent intentLlamada = new Intent(getApplicationContext(), GestionLlamadas.class);intentLlamada.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);intentLlamada.putExtra("tipoLlamada", "Nº Llamada perdida: " + numero_llamada.toString());intentLlamada.putExtra("datosLlamada", "Hora de la llamada: " + hora_llamada_perdida.toString());PendingIntent pIntentLlamada = PendingIntent.getActivity(getApplicationContext(), request, intentLlamada, 0);NotificationCompat.Builder ntfBuilder = new NotificationCompat.Builder(getApplicationContext()).setContentTitle("Llamada perdida de: " + numero_llamada).setSmallIcon(R.drawable.llamada_perdida).setTicker("Llamada perdida")//Método que permite controlar la visibilidad de la información contenida en las notificaciones//que se mostrarán en la pantalla de bloqueo del dispositivo. Se pasa como parámetro un valor entero con la constante//VISIBILITY_PUBLIC, que posibilita la visualización completa de los datos de la notificación..setVisibility(NotificationCompat.VISIBILITY_PUBLIC).setCategory(NotificationCompat.CATEGORY_CALL)//Método para establecer el color del círculo situado detrás de la imagen de la notificación,//para controlar una visualización correcta del icono con el nuevo estilo material design. Recibe como parámetro//un valor entero con el sistema de colores argb..setColor(Color.RED).addPerson(ContactsContract.Contacts._ID)//Este método permite lanzar un intent en lugar de publicar la notificación en la barra de estado,//mostrándola en una ventana flotante o también denominada notificación heads-up. Recibe entre sus parámetros el//intent a lanzar, y un valor booleano con el grado de prioridad, que si se establece en true, siempre//será enviado incluso si se han suprimido las notificaciones..setFullScreenIntent(pIntentLlamada,true).addAction(R.drawable.llamada_perdida, "Llamada perdida: " + edTelefono.getText().toString(), pIntentLlamada);NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);notificationManager.notify(NOTIFICACION_ID, ntfBuilder.build());}}; - Por último comentar que se declaran e inicializan dos objetos de la clase
Timer
, que se encargarán de invocar al métodorun()
, pasado un determinado periodo de tiempo, a partir del lanzamiento del eventosetOnClickListener()
por parte del usuario. Con este sistema, el de establecer un periodo de tiempo para la realización de la tarea, se pretende mostrar cómo se visualizarán las notificaciones flotantes durante el uso de cualquier aplicación que se esté ejecutando en el dispositivo:
1234567891011121314151617181920212223242526272829303132/*Evento que controla el cambio de estado del botón 'Notificar Email' cuando este es pulsado,creando una notificación en la barra de estado, con la información de la dirección deemail y asunto del correo.*/btnNotificarEmail.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {/*Se declara e inicializa la clase Timer, que posibilita la programación de la tarea de crear una notificación de un email recibido.El objeto creado, invocará al método schedule(), que recibirá entre sus parámetros la tareaa realizar y el tiempo de espera hasta la ejecución de dicha tarea.*/Timer timer = new Timer();timer.schedule(tareaEmail, INICIAR_ACCION);Toast.makeText(MainActivity.this, "Nueva notificación: Email recibido",Toast.LENGTH_SHORT).show();}});/*Evento que controla el cambio de estado del botón 'Notificar Llamada' cuando este es pulsado,creando una notificación en la barra de estado, con el número de teléfono indicado.*/btnNotificarLlamada.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {/*Se declara e inicializa la clase Timer, que posibilita la programación de la tarea de crear una notificación de llamada perdida.El objeto creado, invocará al método schedule(), que recibirá entre sus parámetros la tareaa realizar y el tiempo de espera hasta la ejecución de dicha tarea.*/Timer timer = new Timer();timer.schedule(tareaLlamada, INICIAR_ACCION);Toast.makeText(MainActivity.this, "Nueva notificación: Llamada perdida",Toast.LENGTH_SHORT).show();}});
Nota: En el ejercicio práctico comentado anteriormente, se ha descrito sólo el código que hace referencia a las novedades que presenta a nivel de notificaciones la nueva versión de Android 5.0 Lollipop, sin entrar a detallar el resto del código que ya ha sido comentado en anteriores tutoriales.
Descarga Proyecto
DownloadEn la próxima entrega de esta serie (sábado 25), publicaremos un videotutorial Premioum explicando este proyecto.