contacto[arroba]digitallearning.es

Android 6.0: desarrollo App ejemplo con gestión de permisos

Post Series: Android 6.0 Marshmallow

Vamos a desarrollar un proyecto Android para ver de forma práctica la asignación de permisos de una App en tiempo de ejecución, una de las novedades más interesantes de Android 6.0 Marshmallow.

En este proyecto, la App Android creada solicitará de manera explícita al usuario, la necesidad de asignar permisos de lectura de los contactos y del estado del teléfono.

Empezamos describiendo la estructura general del proyecto, para explicar a continuación, más en detalle, las clases, métodos y demás elementos que contendrá. Como siempre, podrás descargar el código completo al final de este tutorial.

Estructura y elementos del Proyecto Android

Mostramos en el siguiente diagrama las pantallas de la aplicación, con el flujo natural de uso de esta app (pincha para ampliar):

Lógica App Android 6.0

Comenzamos enumerando los elementos necesarios para el desarrollo del proyecto denominado “Android60″:

  • 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 ListActivity, y que además implementa la interfaz ActivityCompat.OnRequestPermissionsResultCallback, cuya tarea será solicitar en tiempo de ejecución los permisos necesarios para la lectura de los contactos y el estado del teléfono.
  • Clase AdaptadorContactos, que herede de la clase base BaseAdapter, encargado de construir la vista de cada uno de los contactos que se mostrará en el componente ListView.
  • Clase Contacto, que definirá el constructor con los argumentos para la creación de un nuevo objeto Contacto, además de los métodos de acceso getter y setter para las propiedades privadas.
  • 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 dos controles de tipo Button, encargados de solicitar los permisos de lectura de contactos y estado del teléfono, un control de tipo TextView, que mostrará el estado del teléfono, y un control de tipo selección ListView, que mostrará el listado de contactos.
  • Layout contactos.xml, que definirá la vista personalizada de cada ítem que construya el control ListView.

Estructura del proyecto

Aquí podemos ver la estructura de esta Aplicación:

Estructura Proyecto Android 6.0

 

Documentación código fuente

A continuación revisaremos más en detalle las clases y ficheros de layout de la aplicación

Android_6_0\app\src\main\java\com\academiaandroid\android_6_0\MainActivity.java

Se define la clase MainActivity, que hereda de la clase base ListActivity, y que además implementa la interfaz ActivityCompat.OnRequestPermissionsResultCallback, cuya tarea será solicitar en tiempo de ejecución los permisos necesarios para la lectura de los contactos y del número del dispositivo:

Continuando con la clase comentada anteriormente, se declaran dos variables de tipo int, que permitirán definir identificadores únicos asociados a cada uno de los permisos que se solicitarán en tiempo de ejecución:

Posteriormente, dentro del método onCreate(), se asocian las variables de tipo TextView, View, Button y ListView declaradas, con sus controles a nivel de layout. Además se implementa la lógica de eventos onClick para solicitar los permisos de lectura de contactos y de acceso al estado del teléfono:

Al pulsar el botón, se comprobarán los permisos disponibles para la tarea a realizar, solicitándolos en caso de que no estén asignados:

Otro de los métodos a comentar dentro de esta clase, sería el método peticionPermisos, que se encargará de solicitar los permisos necesarios al usuario mediante el sistema de notificaciones Snackbar (Material Design):

Como curiosidad, para la descripción de los permisos solicitados, se utiliza el tipo de notificación Snackbar, y que invocando al método make, permitirá mostrar un mensaje emergente desde la parte inferior de la pantalla, recibiendo como parámetros de entrada la View donde se mostrará la notificación, el texto a mostrar, y la duración del mensaje (es posible utilizar la constante Snackbar.LENGTH_INDEFINITE, que mantendrá el mensaje en pantalla hasta que el usuario pulse el botón definido). Para este último caso, será necesario invocar al método setAction, donde se muestra el texto a pulsar por el usuario, y el evento onClick que contiene la acción a realizar (en este caso la solicitud de permisos en tiempo de ejecución):

Al no aceptarse los permisos, se solicitarán de manera directa:

Continuando con la clase MainActivity, nos encontramos con el método onRequestPermissionsResult, que será llamado cuando el usuario acepte el permiso requerido. Dicho método será implementado por la interfaz ActivityCompat.OnRequestPermissionsResultCallback:

Identificador para realizar la tarea de lectura de contactos:

Permiso aceptado, se podría acceder a los contactos del dispositivo. En este caso, se listan utilizando el control de tipo selección ListView:

Permiso denegado. Desactivar la funcionalidad que dependía de dicho permiso:

Identificador para realizar la tarea de recibir el estado del teléfono:

Permiso aceptado, se mostrará el número del teléfono:

Permiso denegado. Desactivar la funcionalidad que dependía de dicho permiso:

Por último dentro de esta clase, se define el método encargado de devolver la lista de objetos Contacto, almacenados en el dispositivo:

Se declara una instancia de ContentResolver, a la que se le asigna el método getContentResolver(), que proporciona el acceso a los datos del Content Provider:

Se recorrerán los resultados almacenados de la consulta en el objeto Cursor, comprobando en cada iteración que existe el registro siguiente:

Se controla el tipo de contacto para asignarle los valores de ‘Teléfono Casa’ o ‘Teléfono móvil’:

Se crea un objeto de la clase Contacto por cada iteración, con los valores de tipo, datos y número de contacto:

Android_6_0\app\src\main\java\com\academiaandroid\android_6_0\AdaptadorContactos.java

Como es habitual cuando utilizamos un control ListView personalizado, se define una nueva clase llamada AdaptadorContactos, que hereda de la clase base BaseAdapter, y que construirá la vista personalizada de cada uno de los contactos disponibles en el dispositivo:

Se asocian las variables de tipo TextView con sus controles a nivel de layout:

Se asigna a cada control los datos de nombre, teléfono y tipo de contacto:

Clase estática donde se declaran las variables de tipo TextView:

AndroidStudioProjects\Android_6_0\app\src\main\res\layout\activity_main.xml

A nivel de layout, tendríamos activity_main.xml, que define el layout de la Activity MainActivity.java, y en el que se implementan dos controles de tipo Button encargados de solicitar los permisos de estado y contactos del teléfono, un control de tipo selección ListView, que mostrará el listado de contactos disponibles, y un control de tipo TextView, que mostrará el número de teléfono del dispositivo:

AndroidStudioProjects\Android_6_0\app\src\main\res\layout\contactos.xml

Layout que define la vista personalizada de cada uno de los contactos que se mostrarán en el control ListView, y que estará formado por tres controles de tipo TextView y un control ImageView con el logo de la aplicación:<?xml version=”1.0″ encoding=”utf-8″?>
<TableLayout …

Permisos declarados en AndroidManifest.xml

Por último recordar que será necesario declarar dentro del AndroidManifest.xml los diferentes permisos necesarios para la lectura de contactos y estado del teléfono. Como se puede apreciar, esta sería la sintaxis del nuevo modelo de permisos de Android 6 Marshmallow:

Dependencias gradle implementadas

Será necesario añadir las dependencias para hacer uso de la notificación Snackbar que proporciona Material Design:

Descarga del proyecto

A continuación puedes descargar todo el código de la Aplicación:

Descargar

Para finalizar esta serie, en la próxima publicación describiremos este proyecto en un video, viendo además el funcionamiento de la aplicación.