Android: Guión para crear tu propia aplicación - APPcontecimientos

Rafa Morales 26 Septiembre 2017
20min
0
Interfaz de usuario

Os proponemos aprender a programar en Android creando vuestra propia aplicación. Se trata de un guión donde te diremos qué debes hacer y dónde puedes encontrar la documentación que te ayude a realizarlo. Cuando no indico nada de documentación es porque ya se ha realizado en apartados anteriores y deberías saber hacerlo. Espero que os sea de ayuda.

 

Objetivos del proyecto "APPcontencimientos"

Realizaremos una aplicación que nos permita buscar en un servidor de Internet los acontecimientos publicados en él y nos descargue toda la información a nuestros dispositivo. De esta manera podremos consultar dicha información de manera offline en cualquier momento.

Un pequeño boceto sobre la navegación entre pantallas que tendrá que seguir nuestra aplicación se puede consultar en el siguiente enlace:

La información de los acontecimientos se encuentra accesible en formato JSON a través de un servidor REST. La información se divide en el "acontecimiento" que almacena la información general, y en los "eventos" que detallan dicha información. Los detalles los podéis encontrar en el siguiente enlace:

 

Conociendo Android Studio y creando "Hola mundo"

Para el desarrollo de aplicaciones Android, Google nos ofrece un Entorno de Desarrollo preparado con todas las herramientas necesarias para facilitar nuestro trabajo. Realizaremos los siguientes pasos para ir conociéndo Android Studio y crear nuestra primera aplicación (Documentación para todos los puntos).

  • Cómo instalar Android Studio y qué instalar del SDK .
  • Cuál es la estructura básica de un proyecto en Android Studio.
  • Cuáles son los componentes básicos de una aplicación Android.
  • Desarrollar una aplicación de ejemplo Android, "Hola Mundo".
  • Conocer el emulador nativo de Android Studio.
  • Conocer emuladores alternativos externos a Android Studio.
  • Cómo utilizar mi propio móvil para probar mi aplicación.

 

Comenzando el proyecto "APPcontecimientos" y diseñando la pantalla de logo

Comienza tu proyecto creando una nueva aplicación que funcione en versiones de Android 4.1 o superiores. Dedícale un rato a pensar un nombre y un logo que la identifique. En Internet encontrarás multitud de recursos libres de uso que podrás añadir a tu proyecto (Documentación).

Como muchas aplicaciones del mercado, vamos a hacer que la primera pantalla que de nuestra aplicación muestre el logo y el nombre de nuestra aplicación. Nuestro proyecto debe incluir recursos de imágenes, cadenas, etc. Debemos aprender a incluirlos y a utilizarlos (Documentación).

También debemos conocer los estilos y colores, así como las unidades de medida que se utilizan en los dispositivos (Documentación).

Para realizar un buen diseño de su interfaz debes conocer los fundamentos de Material Design (Documentación).

Utiliza un clase para almacenar todas los valores constantes de tu aplicación y así poder modificarlos más rápidamente (Documentación).

 

El log de la aplicación y su depuración

Android Studio trae implementada la opción para depurar paso a paso la aplicación que desarrolles, una función muy útil para comprender su ejecución y subsanar errores (Documentación).

Tanto las aplicaciones como el propio sistema Android permiten mostrar mensajes de Log para informar de sus actividad o de posibles errores. Conoce qué niveles de Log existe, cómo acceder al log desde Android Studio y cómo crear mensajes de Log en tu aplicación (Documentación).

Crea tu propia clase "MyLog" y utilízala en tu código en lugar de "Log". En todas tus actividades y fragmentos, sobreescribe siempre los métodos que definen el ciclo de vida del mismo y envía un mensaje de log cuando se inicie. De esta manera podrás conocer en cada momento qué metodos se han ejecutado y te ayudará a comprender mejor su funcionamiento (Documentación).

Android Studio nos permite también depurar nuestra aplicación para ver paso a paso su ejecución (Documentación).

Acostúmbrate a comentar el código fuente de tu aplicación.

 

Diseñando una aplicación multilenguaje

Anteriormente hemos utilizado el recurso "string" para representar cadenas en la aplicación, podemos ampliar su funcionamiento traduciendo estas cadenas a diferentes idiomas para hacer que nuestra aplicación tenga funcionalidad de multilenguaje. Cambiando el idioma de nuestro dispositivo se cambiará automáticamente el idioma de nuestra aplicación (Documentación).

 

Iniciando la pantalla del listado de acontecimientos locales

Crearemos una actividad básica (que incluye un botón flotante y una barra de herramientas) para mostrar los acontecimientos almacenados localmente en nuestro dispositivo, aunque ahora mismo en ella sólo mostraremos un "TextView" que indique "Aún no has añadido ningún acontecimiento" (Documentación).

A esta actividad se accederá automáticamente tras mostrarse durante unos segundos la actividad del logo (Documentación).

Analizaremos el Ciclo de Vida de una Actividad. Incluiremos en el código Java de la actividad los métodos de cada estado de la Actividad, y en cada uno de ellos enviaremos mensajes al Log para comprobar que se ha entrado en ese estado (Documentación).

Según vamos mostrando actividades en nuestra aplicación, éstas se van mostrando encima de las anteriores, pero también podemos matarlas para que desaparezcan de la misma. Debemos conocer el funcionamiento de la pila de actividades en una aplicación para manejar correctamente las actividades (Documentación).

Las actividades deben controlar los botones "Up" y "Back" para navegar entre ellas. En nuestro caso vamos a matar la actividad del logo, por lo que al pulsar el botón "Back" de nuestra aplicación saldremos de la misma, al no existir más actividades. Y como es la primera actividad, el botón "Up" tampoco debe aparecer (Documentación).

 

Definiendo la pantalla AcercaDe

Las aplicaciones suelen tener una pantalla en la que se muestra la información del creador y/o desarrollador de la misma, licencias y toda la información que creas necesaria. Crearemos una actividad para mostrar la información del desarrollador de la aplicación y definiremos sus botones "Up" y "Back".

Modificaremos el "Toolbar" de la pantalla del listado de acontecimientos locales para incluir en el menú una opción que abra esta actividad (Documentación)

 

Iniciando la pantalla para buscar acontecimientos

Al pulsar el botón flotante del listado de acontecimientos locales, accederemos a una nueva pantalla donde podremos buscar acontecimientos publicados en el servidor REST mediante su nombre.

Comenzaremos creando una actividad en la que aparezca un "EditText" donde se introducirá el texto a buscar y un "Button" para comenzar la búsqueda.

Tras pulsar el botón, el primer paso es comprobar si se han introducido al menos tres caracteres en el campo de búsqueda, en caso contrario se mostrará una notificación del tipo "SnackBar" para indicárselo al usuario. (Documentación).

En el momento de pulsar el "Button" tendremos que ocultar el teclado por si mostramos una notificación. (Documentación).

EXTRA (1):

En lugar de la notificación con "SnackBar" se puede deshabilitar el "Button" hasta que en el "TextView" se hayan introducido tres caracteres.

EXTRA (2):

Preparar el formulario de búsqueda con las opciones necesarias para buscar por diferentes valores (localidad, provincia o fecha).

 

Comprobando los permisos

Tras pulsar el botón y comprobar que el usuario ha introducido texto, lo que vamos a hacer es comprobar si el usuario tiene los permisos que vamos a necesitar durante el proceso de búsqueda.

Comenzaremos comprobando los permisos de Internet, de acceso al estado de la red y al estado del wifi. Si la aplicación no tuviera alguno de esos permisos se mostraría un "SnackBar" al usuario para informarle de ello (Documentación).

Si tenemos los permisos anteriores, comprobaremos que tenemos o la red o el wifi activos. Si ninguno de los dos estuviera activo se mostraría un "SnackBar" al usuario para informarle de ello (Documentación).

A continuación comprobaremos el permiso para escribir en la memoria externa. Si la aplicación se ejecuta en la versión Marshmallow o superior, al ser un permiso peligroso, hay que pedirle al usuario que acepte o rechace dicho permiso en tiempo de ejecución. Si la aplicación se ejecuta en una versión inferior, sólo realizaremos la comprobación. En ambos casos, si no se tuviera ese permiso, se mostraría un "SnackBar" al usuario para informarle de ello (Documentación).

EXTRA:

En el "SnackBar" que indique que ni la red ni el wifi están activos, se puede incluir un enlace a la configuración de red del dispositivo y que el usuario pueda habilitarlo.

 

Descargando los datos mediante una tarea asíncrona con barra de progreso

Para realizar una conexión a un recurso de Internet, Android nos obliga a realizar una "AsyncTask" (tarea asíncrona) y de esa manera que el usuario pueda seguir trabajando con la aplicación.

Si todas las comprobaciones anteriores con los permisos son correctas, como tercer paso tras pulsar el "Button" será lanzar la "AsyncTask", a la que le pasaremos como parámetro la cadena de búsqueda que el usuario ha introducido (Documentación).

Una vez dentro de la tarea asíncrona realizaremos la conexión al servidor REST, obteniendo el contenido de la respuesta. Lo mostramos en el log para comprobar que la conexión ha sido existosa (Documentación).

En el caso de que no se pueda realizar la conexión al servidor REST se le notificará al usuario mediante un "SnackBar". La "AsyncTask" debe recibir también como parámetro el contexto de la actividad para poder mostrar la notificación.

Mientras se realiza la "AsyncTask" mostraremos una "ProgressBar" para que el usuario sepa que se está realizando el proceso en segundo plano (Documentación).

 

Analizando los datos descargados

Si se ha realizado correctamente la conexión y nos hemos descargado los datos del servidor, debemos analizarlos para comprobar que están en el formato JSON que nosotros esperamos. Iremos recorriendo los datos (Documentación).

En el caso de que los datos recuperados no posean el formato correcto se le notificará al usuario mediante un "SnackBar".

En el caso de que los datos recuperados sean correctos, los mostraremos en el log simplemente para visualizarlos como comprobación.

En el caso de que los datos recuperados indiquen que la búsqueda no ha devuelto ningún resultado, bajo el "EditText" y el "Button" de la búsqueda mostraremos en un "TextView" el mensaje para que el usuario realice otra búsqueda.

 

Mostrando los datos descargados

En el caso de que los datos descargados sean correctos, los almacenaremos en un "Adapter" (adaptador) para posteriormente mostrarlos en la actividad dentro de un RecyclerView  bajo el "EditText" y el "Button" de la búsqueda (Documentación).

 

Almacenando datos en una base de datos local

Al pulsar uno de los acontecimientos del "RecyclerView", tendremos que hacer una nueva "AsyncTask" para descargarnos los datos en concreto de ese acontecimiento. Al igual que antes, debemos comprobar la conexión al servidor REST y que los datos descargados sean correctos. Cualquier error debemos notificarlos con un "SnackBar".

Si los datos descargados son correctos, procederemos a almacenarlos en un base de datos SQLite en nuestro dispositivo local. Para eso debemos dotar a nuestra aplicación del permiso de escritura en almacenamiento externo y, para las versiones superiores a Marshmallow, pedir dicho permiso en tiempo de ejecución.

Debemos crear la base de datos local (con los tipos de datos que permite SQLite), pero podemos modificar el directorio por defecto donde se almacena la base de datos mientras se desarrolla la aplicación para poder analizarla con otras aplicaciones (Documentación).

A continuación insertamos en la base de datos los datos recuperados del acontecimiento y sus eventos. Aunque previamente deberíamos eliminar de la base de datos los datos del mismo acontecimiento y sus eventos (para evitar errores de duplicidad de clave) (Documentación).

Mientras se realiza la "AsyncTask" se puede mostrar un "ProgressBar" que le muestre al usuario que se está procesando en segundo plano (Documentación).

En el caso de cualquier error con la base de datos se le notificará al usuario mediante un "SnackBar".

 

Registrando el acontecimiento descargado

En el caso de que la inserción del nuevo acontecimiento sea correcta, utilizaremos los "SharedPreferences" para almacenar de forma permanente el identificador del acontecimiento que nos acabamos de descargar y así poder conocerlo posteriormente (Documentación).

 

Mostrando los datos de un acontecimiento local

A continuación la actividad de búsqueda se finalizará y se abrirá una nueva actividad que muestre los datos generales de un acontecimiento (pero no los datos de sus eventos).

Para ello, en primer lugar recuperaremos del SharedPreferences el identificador del acontecimiento almacenado, en segundo lugar recuperaremos los datos de la base de datos local (Documentación) y en tercer lugar crearemos los elementos de texto e imágenes que existan en tiempo de ejecución (Documentación).

 

Retomando la pantalla del listado de acontecimientos locales

La pantalla del listado de acontecimiento locales la teníamos en blanco, ahora ya podemos recuperar los acontecimientos que tenemos almacenados en la base de datos local y mostrar en una lista del tipo "RecyclerView" con ellos. Debemos comprobar de nuevo el permiso de escritura en almacenamiento externo y, para las versiones superiores a Marshmallow, pedir dicho permiso en tiempo de ejecución.

Al pulsar un acontecimiento del listado se almacenará su identificador en "SharedPreferences" y se accederá a la pantalla que muestre los datos de dicho acontecimiento.

Esta pantalla debe mostrar un mensaje en un "TextView" cuando no existan acontecimientos almacenados localmente.

 

Utilizando fragmentos para mostrar los eventos

Como un acontecimiento puede tener ninguno, uno o varios eventos, vamos a aprovechar las ventajas que nos proporcionan los fragmentos para mostrar en uno de ellos la lista con el nombre de los eventos y en otra los detalles de cada evento una vez que se pulse en el nombre. Si el móvil está en vertical los fragmentos se intercambiarán en la pantalla. Si el móvil está en horizontal los fragmentos aparecerán al mismo tiempo uno al lado del otro. (Documentación). Debemos comprobar de nuevo el permiso de escritura en almacenamiento externo y, para las versiones superiores a Marshmallow, pedir dicho permiso en tiempo de ejecución.

El fragmento del listado mostrará los nombres de los eventos junto con la fecha y hora de inicio, ordenados estos de manera ascendente.

El fragmento de los detalles mostrará en tiempo de ejecución los elementos de texto e imágenes de dicho evento.

 

Eliminando acontecimientos

Dentro de la pantalla de datos del acontecimiento mostraremos un menú en la barra de herramientas con el que eliminaremos de la base de datos local los datos de ese acontecimiento y sus eventos (Documentación). Mediante un diálogo preguntaremos al usuario si está seguro de querer aliminarlo (Documentación). Debemos comprobar de nuevo el permiso de escritura en almacenamiento externo y, para las versiones superiores a Marshmallow, pedir dicho permiso en tiempo de ejecución.

EXTRA:

Configurar en el RecyclerView del listado de acontecimientos locales la opción de eliminar los datos de un acontecimiento y sus eventos mediante el gesto "swipe" (deslizamiento) de ese elemento (Documentación) o mediante un icono a la derecha dentro del mismo RecyclerView. En estos dos casos el método de borrado se ejecuta dentro del Adaptador del RecyclerView, debe recibir la Actividad como parámetro para poder llamar a un método de ella que actualice el contenido del RecyclerView.

 

Añadiendo opciones de configuración

Gracias a "PreferenceActivity" podemos dotar a la aplicación de una pantalla de opciones de configuración que se almacenan de manera automática sin nosotros tener que preocuparnos por su implementación. (Documentación). Le vamos a añadir a la aplicación las siguiente opciones:

  • Cambiar el lenguaje de la aplicación entre español e inglés.
  • Permitir acceder directamente al último acontecimiento visitado cuando abrimos la aplicación, sin pasar por la pantalla del listado de acontecimientos.

CONSEJOS:

Para acceder al último acontecimiento visitado, dentro de la pantalla de logo podemos comprobar dicha opción, y después de lanzar la actividad del listado podemos lanzar la actividad para mostrar los detalles del acontecimiento, de esa manera tendremos en la pila las dos actividades preparadas.

 

Utilizando Google Maps

Podemos incrustar en una actividad la visualización de un mapa de Google Map en la que mostremos marcadores con la posición general del evento en un color y la posición de todos sus eventos en otro color. Posicionaremos el mapa en el marcador del acontecimiento y realizaremos un zoom que se acerque para visualizar la zona (Documentación). Debemos comprobar de nuevo el permiso de escritura en almacenamiento externo y, para las versiones superiores a Marshmallow, pedir dicho permiso en tiempo de ejecución.

Podemos habilitar el botón de "Mi Ubicación" en la pantalla para que el usuario se pueda posicionar y localizar el lugar del acontecimiento. (Documentación).

EXTRA:

Habilitar la barra de herramientas en la pantalla del mapa y mostrar el "Up Button".

Realizaremos un zoom al mapa para mostrar todos los marcadores mostrados en el mapa.

 

Utilizando el navegador web interno

Como los datos del acontecimiento y los eventos incluyen referencias a páginas webs como Facebook, Twitter, etc; vamos a mostrarlas en pantalla mediante un icono que al pulsarlo abra una actividad en la que se incluya un navegador web (WebView) que muestre el contenido de la página y permita navegar por ella, es decir, sin utilizar el navegador por defecto del dispositivo. La actividad recibirá como parámetro en el "Intent" la URL que debe cargar.  (Documentación).

 

Utilizando Intents 

Al pulsar los datos del teléfono se realizará un "Intent explícito" que realice el marcado telefónico de dicho número en el dispositivo. (Documentación).

Crear un nuevo icono que permita compartir por correo electrónico los datos del acontecimiento y sus eventos. Se realizará mediante un "Intent implícito" que busque una aplicación de correos electrónicos en el dispositivo. (Documentación).

 

Utilizando Intent-filters

Prepararemos una nueva actividad en nuestra aplicación que permita recibir datos desde cualquier aplicación. Configuraremos un "Intent-filter" en nuestra aplicación que permita recibir texto plano. (Documentación). Al recibir el texto se abrirá la pantalla de acontecimientos locales, al pulsar en uno de los acontecimientos se asociará ese texto a dicho acontecimiento. Para ello crearemos una nueva tabla en la base de datos donde almacenaremos asociaremos el identificador del acontecimiento y el nuevo texto.

CONSEJOS:

Al pulsar el elemento del acontecimiento comprobaremos si hemos entrado desde el Inten-filter, en este caso almacenaremos la información en lugar de dirigirnos a la pantalla de datos del acontecimiento.

EXTRA:

Configurar un "Intent-filter" en nuestra aplicación que permita recibir imágenes.

 

Utilizando Broadcast-receivers

Preparamos nuestra actividad para recibir los "Broadcasts" de cambios en el estado de la red de datos y Wifi. Cuando se deshabiliten datos y WiFi se debe mostrar un "Toast" indicándolo. El BroadcastReceiver debe programarse dinámicamente sólo en la pantalla del listado de acontecimientos. (Documentación).

 

Manejando notificaciones Push

Las notificaciones Push se envían desde Internet a nuestro dispositivo para avisarnos de algún suceso. (Documentación).

La aplicación se registrará en OneSignal para recibir notificaciones Push enviadas desde allí. Estas notificaciones se recibirán aunque la aplicación esté abierta.

La notificación llevará asociados unos datos adicionales (AdditionalData) con información del ID del acontecimiento. Al pulsar en la notificación se abrirá directamente el acontecimiento en función de esos datos adicionales.

Las notificaciones se deben enviar filtradas a OneSignal para que sólo se emitan a los móviles registrados que se hayan descargado dicho acontecimiento.

 

Insertando publicidad

Utilizaremos el programa de publicidad de Google AdMob para insertar un banner de pruebas en la pantalla del listado de acontecimientos locales. (Documentación).

 

Definiendo widgets

Crear un widget que pueda ser utilizado en el dispositivo para mostrar el próximo acontecimiento de los que tenemos almacenados en local. (Documentación).