Академический Документы
Профессиональный Документы
Культура Документы
El desarrollo de aplicaciones para Android no requiere aprender lenguajes complejos de programacin. Todo lo que se necesita es un conocimiento aceptable de Java y estar en posesin del kit de desarrollo de software o SDK provisto por Google el cual se puede descargar gratuitamente
Mikon
Android
Contenido
Introduccin .................................................................................................................................. 2 0.- Empezando............................................................................................................................... 4 1.- Fundamentos de una aplicacin .............................................................................................. 8 2.- Recursos de una aplicacin .................................................................................................... 11 3.- La clase Activity ...................................................................................................................... 15 4.- La clase Fragment................................................................................................................... 23 5.- View personalizada ................................................................................................................ 27 6.- Adaptadores (Adapter) .......................................................................................................... 30 7.- La clase Intent ........................................................................................................................ 32 8.- Receptores de mensajes broadcast (Broadcast Receiver) ..................................................... 37 9.- Preferencias de una app (Shared Preferences)...................................................................... 38 10.- Bases de datos SQLite .......................................................................................................... 40
Introduccin
A da de hoy, Android dispone de cientos de millones de dispositivos mviles en ms de 190 pases a lo largo del mundo. Y todo ello acompaado de ms de 1.5 billones de descargas de aplicaciones desde Google Play cada mes. Unos nmeros asombrosos que a muchas personas les han llevado a querer aportar su granito de arena, desarrollando su propia aplicacin. Quin no ha pensado tener esa idea que poder llevar a cabo?
Por ello, y aportando mi propia experiencia como desarrollador de apps para Android, vamos a comenzar un nuevo manual orientado a introducirnos al desarrollo de aplicaciones para Android: la seccin Aprende Android en 20 conceptos. En este manual haremos un recorrido por los 20 fundamentos bsicos de la API (Application Programming Interface) de Android para poder programar una aplicacin en Android, desde cero. Para quien no conozca lo que es una API, bsicamente se trata de la funcionalidad que nos proporcionan (en este caso Android) para poder programar. Esto no quiere decir que con estos 20 conceptos lo conozcamos todo, ni por supuesto que no haya otros conceptos tambin importantes. De lo que se trata es de explicar aqu los conceptos generales ms importantes para crear una buena estructura de nuestra aplicacin. Con esta base, profundizar en conceptos ms especficos (como por ejemplo puede ser el acceso al GPS) ser mucho ms sencillo.
Los 20 conceptos que trataremos en este manual Aprende Android en 20 conceptos son los siguientes: 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. Empezando Fundamentos de una aplicacin Recursos de una app La clase Activity La clase Fragment View personalizada Adaptadores (Adapter) La clase Intent Receptores de mensajes broadcast (Broadcast Receiver) Preferencias de una app (Shared Preferences) Bases de datos SQLite Servicios (La clase Service) Tareas asncronas (La clase AsyncTask) Gestores de contenidos (Content Provider) La barra de acciones ActionBar Notificaciones Orientacin del dispositivo Animaciones Widgets Otros conceptos Informacin adicional
0.- Empezando
Lo primero ser saber que para programar aplicaciones nativas en Android, deberemos aprender a programar en el lenguaje Java, conociendo la programacin orientada a objetos. Lo primero que debemos hacer es preparar nuestro entorno de desarrollo y saber dnde conseguir cualquier informacin. Para ello, lo primero es saber dnde est toda la informacin para los desarrolladores de Android. Google nos tiene preparada una web para ello, pero debemos saber que toda la informacin est en ingls: Web de desarrolladores de Android
En esta web, tenemos 3 secciones bsicas: Diseo, Desarrollo y Distribucin. En ellas, tendremos toda la informacin acerca de las recomendaciones de Google para disear nuestra app, toda la informacin sobre la API de Android e informacin para saber publicar nuestra aplicacin, sabiendo cmo promocionarla, anunciarla En la parte de abajo, tendremos informacin adicional, sobre Android, conseguir el SDK (Software Development Kit), soporte
ste ser nuestro primer paso, descargarnos el entorno de desarrollo, para lo que iremos a Get the SDK, o haremos click en el siguiente enlace: Descargar el SDK
Una vez en la web, basta con que le demos al link que dice Download the SDK, y nos bajar una versin del entorno de desarrollo Eclipse, personalizada para Android y ya preparada con el ltimo SDK, el plugin ADT, as como emuladores sobre los que poder testear nuestra aplicacin. En el pasado Google I/O (2013), anunciaron tambin el nuevo IDE Android Studio, el cual podemos tambin utilizar en lugar de Eclipse, pero debemos saber que an estn en fase beta. Desde la misma pgina podrs acceder a la informacin al mismo. Una vez abrimos nuestro entorno de desarrollo, podemos descargarnos todas las versiones de Android si queremos, as como otros paquetes extra. Para ello utilizaremos el Android SDK Manager.
Por otro lado, podremos crear tantos emuladores de dispositivos Android como queramos: con distintos tamaos de pantalla, distintas versiones de Android Para ello, debemos utilizar el Android Virtual Device Manager (ADB), al cual podemos acceder desde Eclipse o desde la va de comandos de nuestro sistema operativo:
Aunque la mejor manera de tener control sobre nuestros dispositivos ser aprendiendo a manejar. No obstante, en Eclipse podremos gestionar tambin nuestros dispositivos y sacar informacin de nuestro dispositivo: desde capturas de pantalla o ver los ficheros hasta enviar coordenadas GPS o enviar una llamada. Para ello, iremos a Window / Open perspective / Other / DDMS. La vista de Eclipse DDMS (Dalvik Debug Monitor Server) nos ser de gran utilidad mientras desarrollemos nuestras aplicaciones. Disponemos de toda la informacin sobre la misma en el siguiente enlace: DDMS Llegados a este punto, nuestro ordenador est preparado para crear nuestra primera aplicacin Android. Para ello, nos basaremos en los pasos que Google nos recomienda seguir para una sencilla app. Toda esta informacin la podremos encontrar en unos trainings que Google nos tiene preparados: Formacin (Trainings) sobre Android de Google Creando un nuevo proyecto Android
Nuestro primer tema terminar siguiendo el segundo enlace, donde crearemos un nuevo proyecto Android. Para ello, seguiremos los siguientes pasos: Haz click en New 1. En la ventana que aparece, abrir la carpeta Android y elegir Android Application Project 2. En la siguiente ventana, debemos introducir el nombre de nuestra aplicacin, el nombre del proyecto y el nombre del paquete (ste ser nico para nuestra app, pues ser el ID que Google Play utilizar para identificar la aplicacin). Tambin introduciremos la versin de Android mnima requerida, as como la versin con la que compilaremos (generar nuestra aplicacin a partir del cdigo) nuestra aplicacin. 3. Tras rellenar todos los campos segn necesitemos o queramos, nos vamos a la siguiente pantalla, donde dejaremos las opciones seleccionadas por defecto. 4. En la siguiente pantalla, podremos crear un icono para nuestra aplicacin. Para ello, sera ideal echar un vistazo a las guas de diseo de Android con respecto a lo que a iconos se refiere. 5. Por ltimo, seleccionaremos una plantilla de actividad sobre la que empezar a trabajar. Podemos seleccionar Blank Activity, que bsicamente es una pantalla vaca. 6. Finalizamos el asistente.
Con esto, tendremos nuestro particular Hola mundo con el que siempre empezamos a programar cuando utilizamos una nueva API. Para ejecutarlo, basta con tener un dispositivo real conectado o lanzar un emulador y hacer click en el botn Run (un crculo verde con el icono Play en blanco).
Con todas estas reglas, Android consigue implementar lo que se conoce como Principio de menor privilegio, consistente en otorgar los permisos justos a cada aplicacin, de modo que el sistema sea lo ms seguro posible.
Pero todo esto es el funcionamiento por defecto, pues podremos gestionarlo segn nos interese, por ejemplo para compartir datos entre diferentes aplicaciones (un ejemplo perfecto son los Contactos). Una vez conocido como funciona Android, es hora de pasar a definir los componentes de una aplicacin. stos son los bloques bsicos que podemos construir. Hay 4 diferentes tipos de componentes: Activity: Representa una pantalla independiente con una interfaz de usuario. A pesar de que nuestra aplicacin dispondr de mltiples pantallas interconectadas entre s, nosotros deberemos generarlas individual e independientemente (pudiendo pasar datos entre ellas, en caso de ser necesario). Entraremos en ms detalle en esta clase cuando lleguemos al concepto 3. Service: Es un componente que corre de fondo para hacer operaciones de larga duracin o trabajo en procesos remotos. Contrario a la actividad, no dispone de interfaz grfica. Veremos ms detalles al llegar al concepto 11. Content Provider: Este componente nos permite gestionar un conjunto de datos de la aplicacin para compartir. Los Contactos son el ejemplo perfecto para este componente: datos que podemos compartir entre diferentes aplicaciones. Pero podemos crear nuestro propio conjunto de datos (ms detalle en el concepto 13). Broadcast Receiver: El cuarto de los componentes nos permite responder a anuncios broadcast del sistema. Un buen ejemplo es si queremos gestionar cuando tengamos el aviso de batera baja (el cual enviar un mensaje broadcast), aunque podemos disear nuestros propios mensajes (ms detalles en el concepto 8). Un aspecto interesante de diseo de Android es que una aplicacin A podra abrir un componente de una aplicacin B. El ejemplo ideal es cuando queremos usar la cmara en nuestra app, podemos hacer una Activity con la cmara, o abrir el componente de la cmara que viene ya instalada por defecto en el sistema operativo.
Para ello utilizamos un mensaje llamado Intent, el cual tambin sirve para activar 3 de los 4 componentes de una app (todos excepto el Content Provider), Ms adelante veremos cmo hay mtodos especficos para abrir cualquier componente a travs de un Intent (concepto 7).
Pero, cmo sabe nuestra aplicacin qu componentes tiene disponibles? Para ello, existe el fichero AndroidManifest.xml. Este fichero ser el encargado de comunicarle al sistema operativo: Las componentes de las que dispone la aplicacin Los permisos necesarios para la aplicacin (cmara, GPS) La versin de Android mnima necesaria El hardware y software requerido y/o usado Las libreras externas que utiliza (como Google Maps)
Para ello, utilizaremos etiquetas, que en el caso de los componentes sern: <activity> <service> <receiver> <provider> Cada una de estas etiquetas tendr una serie de atributos disponibles, donde indicaremos qu componente en cuestin ser de todos los disponibles, icono o un sinfn de opciones disponibles. Adems, si queremos indicar las capacidades de uno de nuestros componentes, podemos hacer uso de la etiqueta <intent-filter>.
10
A la hora de hacer un buen programa, siempre hay que externalizar los recursos del cdigo, entendiendo por recursos imgenes, textos, estilos De esta forma, tambin podremos especificar diferentes recursos dependiendo del tipo de dispositivo en el que estemos, sin necesidad de modificar el cdigo. Para esto, el ejemplo perfecto es la versin mvil y tablet de una misma pantalla (o Activity, para ir entrando en la jerga): creamos una nica Activity la cual utilizar una distribucin de su contenido diferente segn el tipo de dispositivo que usemos.
Siempre podemos especificar un recurso genrico o por defecto. En contraposicin a ste, tendremos la opcin de especificar que una versin concreta de un recurso es para una configuracin especfica.
11
Para detallar la configuracin especfica podemos basarnos en idiomas, resolucin, orientacin del dispositivo Para ello, basta ver las posibilidades en esta pgina. Bsicamente radica en aadir unas terminaciones a las carpetas donde almacenaremos los recursos, acordes a la configuracin especfica. Todos los recursos irn bajo la carpeta /res. Pero, qu recursos son los que podemos incluir? Los siguientes: Animaciones Colores Imgenes (Drawable) Layouts (Disposicin de elementos grficos) Mens Cadenas de texto (String) Estilos Otros (booleanos, dimensiones) Para ello, deben ir en una estructura de carpetas especfica, de forma que por ejemplo para aadir cadenas de texto en espaol utilizaramos la carpeta /res/values-es o /res/drawable-xxhdpi para Drawables para pantallas de alta resolucin. A continuacin podis ver un diagrama de flujo de cmo Android elige el recurso adecuado:
Teniendo claro cmo se gestionan los recursos, cmo creamos algunos recursos especficos? Veamos a continuacin algunos de ellos: layouts, mens y estilos. Un layout define la estructura visual de una interfaz de usuario. A pesar de que podramos crearla dinmicamente por cdigo, lo ideal es declarar los elementos de la interfaz en un XML.
12
Para crear un layout, disponemos de muchos componentes grficos ya en la API, aunque podemos crear los nuestros propios. Tenemos layouts donde insertar mltiples componentes, vistas de texto, botones A continuacin, podis ver un ejemplo de un layout que nos pondr un texto y justo debajo un botn:
En este caso, un LinearLayout nos pondr elementos uno detrs de otro (en este caso al ser su orientacin vertical, uno debajo de otro). A continuacin un TextView que de ancho y alto ocupa lo que necesite (wrap_content), con el texto Hello, I am a TextView. Y similar para el botn. Cada uno con su identificador nico. Si queremos hacernos buenos a la hora de hacer layouts, lo ideal es que empecemos trabajando con el editor grfico de eclipse o Android Studio, pero vayamos comprobando cmo queda el XML. Conforme pase el tiempo, os daris cuenta que a veces ser ms rpido escribir directamente en el XML. Cuando vamos a definir un men en una de nuestras Actividades, ste tambin se define a travs de un XML. Para ms informacin, os recomiendo visitar el link. Aqu os dejo un ejemplo:
Por ltimo, cuando hablamos de estilos, nos estamos refiriendo al concepto ms parecido a lo que es CSS para una web: externalizar estilos para poder ser reutilizados. Podremos definir estilos para asignarlos a entidades grficas, as como crear un tema para asignarlo a toda la aplicacin.
13
Y como queda tras utilizarlo con estilos, donde el estilo CodeFont podramos reutilizarlo en otras Views, o si decidiramos cambiarlo, podramos cambiarlo a todos a la vez:
Llegados este punto, creo que es el momento de mencionaros la gua de diseo de interfaces para Android, una web donde podremos ver las tendencias y consejos sobre cmo montar una buena interfaz de usuario. Por ltimo, para jugar un poco con la asignacin de recursos para diferentes configuraciones, estara bien que sigis este ejemplo de Google.
14
15
Varias actividades pertenecern a una tarea (task), la cual se define como un conjunto de actividades destinadas a un trabajo determinado. A nivel de Manifest podemos gestionas las tareas, con la definicin de algunos atributos (taskAffinity, launchMode, allowTaskReparenting, clearTaskOnLaunch, alwaysRetainTaskState, finishOnTaskLaunch) y flags o banderas (FLAG_ACTIVITY_NEW_TASK, FLAG_ACTIVITY_CLEAR_TOP, FLAG_ACTIVITY_SINGLE_TOP), de los cuales puedes consultar ms informacin en la documentacin. Sin embargo, el comportamiento por defecto se puede entender bastante bien en este ejemplo: La Actividad A lanza B A para y guarda su estado Le damos al botn Home Se mantiene el estado de cada actividad en la tarea Le damos a Back La actividad actual sale de la pila backstack y se destruye
Como connotacin final sobre la pila backstack, mencionar que las actividades pueden ser instanciadas ms de una vez. Para crear una actividad, basta con que creemos una clase que herede de la clase Activity. Adems de heredar de esta clase, deberemos sobrescribir algunos mtodos que pertenecen al ciclo de vida de la actividad. Este ciclo de vida consiste en los diferentes estados por los que puede pasar una actividad y los mtodos que nos permiten cambiar de un estado a otro. De este modo, podemos distinguir los siguientes estados: Resumed: En este estado, la actividad est en primer plano para el sistema Paused: La actividad est an visible, pero el foco est en otro componente que est por encima de sta Stopped: La actividad an est viva, pero est totalmente oculta
16
De esta forma, podemos distinguir 3 procesos principales en la actividad: Tiempo de vida completo: Entre onCreate y onDestroy Tiempo de vida visible: Entre onStart y onStop Tiempo de vida en primer plano: Entre onResume y onPause Tal como he comentado, en los cambios de un estado a otro, la actividad ir ejecutando una serie de mtodos. Estos mtodos son los considerados pertenecientes al ciclo de vida de la misma. Para nosotros, los dos ms importantes son: onCreate: El sistema llama este mtodo al iniciar una actividad, y en l deberemos iniciar todos los componentes de la actividad. Adems, este mtodo deber llamar siempre al mtodo setContentView, encargado de cargar la interfaz grfica (un recurso layout, indicado a travs de su ID) que la actividad utilizar. onPause: Es el primer mtodo que se llama cuando el usuario est abandonando la actividad. Es el mtodo donde deberemos guardar todos los cambios que queramos que sean persistentes cuando el usuario abandone esta pantalla.
17
Pero cuando queremos optimizar nuestra aplicacin, deberemos sobrescribir tambin otros mtodos del ciclo de vida, los cuales son:
18
Para terminar una actividad, basta con que llamemos al mtodo finish. Como componente de una aplicacin que es, la actividad deber ser registrada en el fichero Manifest. Para ello, utilizaremos la etiqueta <activity> dentro de la etiqueta <application>. Adems, dentro de la actividad, podremos declarar todos los <intentfilter> que queramos, para identificar nuestra actividad y las acciones que puede realizar. Como ejemplo bsico, la actividad considerada main, deber llevar la categora LAUNCHER y la accin MAIN:
19
Llegados este punto, sabemos definir una actividad, incluirla en el Manifest e, incluso, establecerla como la actividad principal. Pero cmo lanzar una actividad? Para ello tenemos dos posibles formas, pero siempre mediante el uso de Intent y el mtodo startActivity: Implcita: Sabemos qu actividad vamos a lanzar, y suele ser una perteneciente a nuestra propia aplicacin
Explcita: Sabemos la funcionalidad que queremos hacer, pero al no conocer qu actividades pueden hacerlo (de nuestra aplicacin o de otras), delegamos en el sistema operativo. ste, segn sus categoras, acciones buscar las posibilidades y nos la dar a elegir. Cmo distingue el sistema entre todas sus actividades? Pues precisamente mediante el uso de los <intent-filter> que hemos mencionado anteriormente.
Adems, podemos necesitar lanzar una actividad pero esperar un resultado para volver a nuestra actividad previa. Para ello, en lugar de startActivity utilizaremos startActivityForResult. De esta forma, podremos registrar los resultados que nosotros deseemos y nuestra actividad previa estar esperando a uno de estos resultados para lanzar alguna funcionalidad especfica:
20
Y qu ocurre cuando una actividad es pausada pero an no destruida? Para ello, podemos hacer uso del salvado de estado de la actividad, sobrescribiendo el mtodo onSaveInstanceState, gracias al cual podremos salvar todos aquellos datos que queramos, y sern recuperados al restaurar la actividad:
21
Otras cosas que podemos hacer con la actividad es registrar cambios en la misma, tales como cambios de orientacin, del estado del teclado, de idioma... Para ello haremos uso del mtodo onConfigurationChanged:
Pero este mtodo slo se disparar ante los eventos que hayamos registrado en el Manifest, mediante el atributo android:configChanges. A continuacin puedes ver un ejemplo de registro de eventos de teclado y de orientacin del dispositivo:
Por ltimo, mencionar que podemos hacer uso de los Loaders, cuando queramos poder precargar de forma asncrona (tanto en actividades como en fragmentos) informacin proveniente de algn ContentProvider.
22
Un fragmento debe siempre ser incluido en una actividad, y su ciclo de vida est totalmente relacionado con el ciclo de vida de la actividad que lo contiene. De esta forma, por ejemplo, si una actividad es pausada, todos sus fragmentos lo sern tambin. He comentado que los fragmentos fueron incluidos en HoneyComb, pero han resultado ser tan trascendentales, que Google nos ha facilitado una librera de retrocompatibilidad, de modo que podamos usar los fragmentos en versiones anteriores, si deseamos que nuestra aplicacin sea compatible (por ejemplo, con Gingerbread). La transicin de fragmentos dentro de una actividad se hace por medio de fragmenttransaction, las cuales podemos aadir a la cola backstack de nuestra actividad. De esta forma, mediante el uso del botn Back podremos deshacer una transaccin de fragmentos y volver a uno anterior, muy similar a como hacamos con la gestin de la cola en las actividades. De todas formas, para gestionar los fragmentos dispondremos de diferentes mtodos, tanto para encontrar un fragmento concreto (findFragmentById /findFragmentByTag) o para gestionar la cola backstack (popBackStack -el cual permite deshacer un cambio del backstack/ addOnBackStackChangedListener).
23
Hemos hablado de que los fragmentos tienen su propio ciclo de vida, pero ntimamente relacionado con el de su actividad contenedora. Si bien esto es cierto, hay que decir que el ciclo de vida es muy similar al de la actividad, pero con ligeras diferencias. En el caso de los fragmentos, la inicializacin de la interfaz grfica o layout se har en el mtodo onCreateView, y no ser llamando al mtodo setContentView, sino que el objeto de la clase View que devuelva onCreateView ser el objeto que se mostrar como interfaz grfica. Para ello haremos uso de un inflater.
Los mtodos que permiten coordinar el ciclo de vida de un fragmento con una actividad son: onAttach: Llamado cuando el fragmento ha sido asociado con la actividad onCreateView: Llamado para crear la vista asociada con el fragmento onActivityCreated: Llamado cuando termine el mtodo onCreate de la actividad onDestroyView: Llamado cuando se elimina la vista asociada al fragmento onDetach: Llamado cuando el fragmento est siendo eliminado de la actividad No obstante, en todo momento tendremos acceso a la actividad contenedora de un fragmento mediante la llamada al mtodo getActivity.
24
Otra opcin muy importante es cuando queremos que un fragmento ejecute cierta funcionalidad asociada a la actividad, que desconoce y tan slo quiere delegar en la actividad e indicarle que debe ejecutarla. Para ello haremos uso de callbacks. Un callback nos permite implementar una interfaz con nuestra actividad, y obtener una instancia de esa actividad implementada en nuestro fragmento y que sea este objeto quien llame a la funcionalidad en cuestin, la cual pertenecer a la actividad. Los fragmentos tendrn los mismos estados que las actividades: resumed, paused, stopped.
25
Puesto que los fragmentos no son componentes de una aplicacin, stos no deben ser declarados en el Manifest. Pero, cmo aadimos un fragmento a una actividad?Para ello, tenemos dos opciones: Declarando el fragmento de manera esttica en el layout de una actividad
Por ltimo, mencionar que Google, para hacernos las cosas ms fciles, nos ofrece algunos fragmentos particulares ya creados, de tal forma que nos resulta mucho ms fcil desarrollar cierta funcionalidad. Entre ellos, encontramos: DialogFragment: Es un fragmento que nos permite mostrar un dilogo ListFragment: Fragmento para gestionar una lista de vistas que se repiten. Perfecto para cualquier lista PreferenceFragment: Fragmento para gestionar preferencias de la aplicacin. Hay que remarcar que este tipo de fragmento no est incluido dentro de los compatibles en la librera de retrocompatibilidad, por lo que no podremos hacer uso de ellos en versiones anteriores a Honeycomb.
26
Puesto que los layouts son algo de lo ms importante para nosotros, aqu tenis toda la informacin respecto a ellos. Con todo esto, ya podramos crear una interfaz grfica, mediante la combinacin de los mismos.
27
Pero, qu hacemos cuando lo que queremos no est disponible en uno de estos objetos incluidos de serie? La respuesta es sencilla: disear el nuestro propio a partir de uno de ellos o de una View genrica.
Al crear nuestra propia View, conseguimos un control preciso sobre la apariencia y la funcionalidad de un elemento que incluiremos en la pantalla. stas son algunas cosas de las que podemos llegar a hacer: Crear una View totalmente personalizada, usando incluso grficos 2D Combinar un grupo de Views en un nuevo componente individual Sobrescribir un componente ya existente para dotarlo de funcionalidad aadida o modificada Capturar otros eventos en algn componente ya creado Analicemos primero la aproximacin bsica. En esta posibilidad, consideramos los siguientes pasos: 1) Crear una clase que extienda de una View ya existente (cualquiera de las anteriores por ejemplo) 2) Sobrescribir alguno de los mtodos de la clase padre. Para saber qu mtodos podemos sobrescribir, todos ellos empiezan por on, como por ejemplo onDraw, onMeasure, onKeyDown 3) Utilizar la nueva clase.
28
Pero si esto no nos provee la funcionalidad que buscamos, deberemos acudir a una vista totalmente personalizada, para la cual deberemos seguir los siguientes pasos: 1) Crear una clase que extienda de la clase View. 2) Proveer un constructor que pueda coger atributos y parmetros del XML o facilitados por nosotros mismos 3) Crear nuestros propios escuchadores de eventos, modificadores 4) Sobrescribir los mtodos onMeasure (si no lo sobrescribimos, por defecto este mtodo devolver una vista con tamao 100 x 100) y onDraw (por defecto no hace nada). De esta forma podremos personalizar lo que mostramos. 5) Sobrescribir otros mtodos de los que empiezan por on. Hemos hablado de los mtodos onMeasure y onDraw, pero para qu sirven exactamente? onMeasure: Es una pieza crtica en el renderizado entre el componente y su contenedor padre. Deberamos sobrescribirlo para poder calcular sus dimensiones de forma eficiente. onDraw: Nos proporciona un Canvas donde podremos implementar cualquier cosa que no sea grficos 3D. Sin embargo, cuando no queremos crear un componente totalmente personalizado y nos gustara juntar varios componentes reutilizables, utilizaremos un componente compuesto. Para ello: 1) 2) 3) 4) El punto de partida habitual suele ser un Layout para nuestra nueva clase Crearemos un constructor, de forma similar a anteriormente Aadiremos todos los escuchadores que creamos convenientes En el caso de que estemos extendiendo de un Layout, podemos olvidarnos de sobrescribir los mtodos onDraw y onMesaure (si queremos) 5) Sobrescribimos los mtodos que empiecen por on que necesitemos Imaginemos que queremos sobrescribir una vista que ya exista. En ese caso deberemos: 1) 2) 3) 4) Definir la nueva vista Inicializar la clase Encargarnos de los mtodos que debemos sobrescribir Usar la nueva vista
29
Qu es un adaptador? Un adaptador (clase Adapter) es un puente de comunicacin entre un AdapterView (el cual nos permite incluir el layout con la vistas en tiempo de ejecucin) y los datos que queremos mostrar en la vista. De esta forma, dinmicamente se ir actualizando la interfaz con nuestros datos. Como siempre, Android nos facilita algunos ya creados por defecto, los ms utilizados. Entre otros, destacan: ArrayAdapter: En este caso los datos estn formados por un Array, y el procedimiento de mostrar los datos en la vista consiste en utilizar el mtodo toString que todo objeto Java tiene para cada elemento del Array. En el caso de que queramos personalizacin adicional, deberemos crear una clase que extienda de ArrayAdapter y sobrescribir el mtodo getView, donde podremos modificar cada vista dinmicamente. Un ejemplo ideal es cuando queremos hacer una lista de TextView.
30
SimpleCursorAdapter: En este caso los datos estn incluidos en un Cursor y ser necesario especificar un layout a utilizar para cada fila del cursor. Cuando queramos notificar que han cambiado los datos en el curso y la interfaz debe actualizarse, bastar llamar al mtodo notifyDataSetChanged.
Por ltimo, mencionar que tambin podremos gestionar eventos como el pulsado (click) en cada elemento. Para ello basta implementar la clase OnItemClickListener.
Con esto, ya deberamos ser capaces de no slo de crear nuestras propias componentes personalizadas (echadle un ojo al cdigo del grfico por sectores!) para la interfaz, sino tambin crear listas de datos de forma dinmica.
31
32
Tal como hemos comentado, habr situaciones en las que sabemos qu componente queremos lanzar. Pero habr otras donde conoceremos qu queremos hacer, pero no qu componente exacto lo hace (por ejemplo, lanzar la cmara). Es por ello que se definen dos tipos de Intents:
Intent Explcito: Este tipo de Intent es aquel en el que conocemos exactamente qu componente lanzar, el cual especificaremos a travs del nombre de componente. Lo utilizaremos cuando querramos lanzar un servicio o actividad, tpicamente de nuestra propia aplicacin. Intent Implcito: En este caso, no conocemos el nombre de componente (estar vaco), pero sabemos la accin que queremos ejectuar. De esta forma, le pediremos al sistema operativo que busque por nosotros qu aplicacin podra realizar dicha accin y, en el caso de que haya varias, nos dar a elegir cul utilizar.
33
La pregunta que nos podramos hacer llegado este punto es: cmo sabe Android qu acciones realiza cada componente de aplicacin? Y aqu es donde juega un papel crucial el fichero Manifest. En l, ya hemos comentado que debemos dejar registrados todos los componentes que forman parte de la aplicacin. Pero no slo eso. Tambin deberemos aadir dentro de cada componente en el Manifest el concepto de Intent Filter. Este filtro nos permite indicar cul es la capacidad de dicha componente. Concretamente, un Intent Filter puede contener los siguientes campos completos: Accin Datos Categora
34
Entonces, cuando nosotros lancemos un Intent implcito, Android buscar en todos los Manifest de todas las aplicaciones instaladas aquellos componentes que cumplan los requisitos de nuestro Intent: todos y cada uno de ellos. Es decir, tendremos que cumplir los requisitos de accin, categora y datos:
35
En el siguiente link, tenis una serie de lecciones donde podis descubrir ms informacin sobre la interaccin con otras aplicaciones a travs de Intents.
36
37
Cuando queramos hacer uso de esta funcionalidad, lo primero que deberemos es conseguir tener un objeto de dicha clase, para lo cual tendremos que usar uno de los siguientes mtodos: getSharedPreferences: Ideal cuando necesitamos varios ficheros de preferencias identificados por nombre, el cual indicaremos como parmetro. getPreferences: Este caso lo utilizaremos cuando slo necesitamos un fichero de preferencias para nuestra actividad, ya que no necesitaremos indicar ningn nombre. Si queremos leer valores, utilizaremos mtodos getters, tales como getBoolean, getString, getInt Pero si queremos escribir datos, deberemos seguir los siguientes pasos: 1. Llamar al mtodo edit para conseguir un objeto de la clase SharedPreferences.Editor 2. Aadir todos los valores que queramos con mtodos put tales como putBoolean, putString, putInt 3. Confirmar los nuevos valores llamando al mtodo commit.
38
Tambin hay que destacar que si lo que queremos es crear preferencias de usuario para nuestra aplicacin, podemos utilizar la clase PreferenceActivity, que nos provee funcionalidad para crear preferencias de usuario que sern automticamente almacenadas de forma persistente, usando precisamente Shared Preferences.
39
Para tener un objeto de la clase creada, basta con que usemos el constructor que hayamos definido. Una vez tengamos el objeto, escribir y leer de la base de datosllamar a los mtodos getWritableDatabase y getReadableDatabase, respectivamente. Ambos mtodos devolvern un objeto de la claseSQLiteDatabase que representa la base de datos y nos provee los mtodos para las operaciones SQLite que queramos. Para ejecutar operaciones SQLite, utilizaremos los mtodos SQLiteDatabasequery, que acepta varios parmetros para nuestra consulta, tales como la tabla, seleccin En el caso de que queramos consultas ms complejas, tambin podemos utilizar la clase SQLiteQueryBuilder. Como resultado a las llamadas anteriores, recibiremos un Cursor que apuntar a las filas encontradas por nuestra consulta. Este Cursor ser siempre para nosotros el mecanismo por el que podremos navegar por los resultados de una consulta a base de datos. Para ir concluyendo, indicar que Android no impone ninguna limitacin a parte de las que tengamos ya por el hecho de usar SQLite. Pero s que se recomienda incluir un valor clave autoincremental para tener un identificador nico para cada entrada en nuestra base de datos. De hecho, si quisiramos usar Content Providers, ser obligatorio su uso. Para ver cmo funcionan las bases de datos SQLite en plena accin, podis echar un vistazo a los ejemplos que nos proporciona Google.
40
o o
START_NOT_STICKY: Si el sistema matase al servicio, no se recrear el servicio a menos que haya an Intents pendientes de ser procesados. Es la opcin ms segura para evitar que el servicio est funcionando cuando no es necesario. START_STICKY: Recrea el servicio y llama a onStartCommand con un Intent null, pero no reenva el ltimo Intent. START_REDELIVER_INTENT: Recrea el servicio y llama a onStartCommand con el ltimo Intent que fue liberado al servicio
Mtodo onBind: Es llamado cuando otro componente quiere asociarse con el servicio. Este mtodo siempre debe ser implementado. En caso de que no queramos permitir asociaciones, basta con devolver null. Mtodo onCreate: Llamado cuando el servicio es creado por primera vez. Mtodo onDestroy: Llamado cuando el servicio no est siendo usado ms y est siendo destruido. Sirve para limpiar recursos de memoria.
41
42
Dentro de su ciclo de vida, podemos distinguir dos fases: Ciclo de vida completo: Entre onCreate y onDestroy. Ciclo de vida activo: Entre onStartCommand/onBind y unBind (en el segundo caso). Para el primer caso no hay un mtodo de finalizacin del ciclo de vida activo.
43
Para crear un servicio, aparte de la clase Service, podemos utilizar la clase IntentService, la cual es una subclase de Service que usa una hebra adicional para administrar todas las peticiones de comienzo, de una en una. Es la mejor opcin si no necesitamos que el servicio administre mltiples peticiones simultneamente.
44
Por ltimo, tambin podremos ejecutar un servicio en primer plano: Ser un servicio considerado a hacer algo que el usuario necesita siempre activo, por lo que no ser un candidato para ser destruido por el sistema cuando haya problemas de memoria. Debe proveer una notificacin en la barra de estado, bajo la cabecera Ongoing, lo que significa que la notificacin no puede ser eliminada a menos que el servicio sea parado o eliminado. Se utilizan los mtodos startForeground/stopForeground
En el siguiente link podrs ver algunos ejemplos de buen uso de los servicios.
45
Actividades que han pasado por onResume Servicios asociados Servicios en primer plano Callbacks de servicios Mtodo onReceive de los BroadcastReceiver
Actividades que no estn en primer plano pero an estn visibles (onPause) Un servicio que est ligado a una actividad visible
Procesos de servicios (servicios en ejecucin que no estn en las otras categoras) Procesos en background (procesos que tienen una actividad que no es visible actualmente al usuario) Procesos vacos (no tienen ningn componente de la aplicacin, normalmente de caching). Por otro lado estn las hebras (Threads). Cuando la aplicacin es lanzada, el sistema slo crea una hebra principal para la interfaz de usuario (UI Thread). Pero, qu ocurrira cuando queramos hacer un trabajo intenso? Estaremos bloqueando la hebra de la interfaz de usuario? La respuesta es s, y es por eso que para trabajos intensos debemos crear nuestras propias hebras. Bsicamente, hay dos reglas bsicas: No bloquear la hebra de la interfaz de usuario o principal
o
Si hiciramos esto, estaramos provocando el famoso error ANR (App Not Responding), el cual aparece cuando bloqueamos la interfaz grfica por unos 5 segundos aproximadamente. Es el error ms molesto de Android, y como desarrolladores es posible evitarlo siguiendo los consejos de Google.
No acceder a la interfaz grfica (Android UI Toolkit) desde fuera de la hebra de la interfaz grfica. Para ello podemos hacer uso de:
o o o
Mtodo runOnUiThread(Runnable) de la clase Activity Mtodo post(Runnable) de la clase View Mtodo postDelayed(Runnable, long) de la clase View
46
Pero para simplificar an ms la posibilidad de realizar trabajos en segundo plano e ir actualizando la interfaz grfica surge la clase AsyncTask, de modo que: Te permite hacer trabajo asncrono en la interfaz grfica Permite operaciones de bloqueo en una hebra secundaria Publica los resultados en la interfaz grfica
47
Respecto al AsyncTask, hay que destacar que cuenta con: Hebra secundaria
o
Hebra principal o de la interfaz grfica. Los siguientes mtodos se ejecutarn en dicha hebra:
o o
Mtodo onPreExecute: Se ejecuta antes de que tenga lugar el mtodo doInBackground Mtodo onPogressUpdate: Se ejecuta cada vez que desde el mtodo doInBackground queramos publicar el progreso con el mtodo publishProgress Mtodo onPostExecute: Se ejecuta al finalizar el mtodo doInBackground
El mtodo publishProgress se ejecutar desde la hebra secundaria, para notificar a la hebra principal que debe llevar a cabo la accin determinada en el mtodo onProgressUpdate
Para iniciar un AsyncTask bastar hacer uso de su constructor y llamar al mtodo execute, .pasndole todos los parmetros que queramos:
Personalmente, como desarrollador de Android, creo que me costara vivir sin la clase AsyncTask, pues la considero tan relevante como lo puede ser la clase Activity.
48
Con todo esto, ya deberamos ser capaces de ejecutar cdigo en segundo plano, algo que resulta vital para el buen desarrollo de una aplicacin, pues siempre debemos dar la impresin de que la interfaz grfica est esperando el feedback del usuario y no que est bloqueada por algn trabajo en cuestin. Poco a poco, vamos teniendo las herramientas ms importantes para el buen desarrollo de una app. Espero que os est resultando til.
49
Una Content URI es una URI que identifica datos en un proveedor. Incluye el nombre simblico del proveedor completo (autoridad) y un nombre que apunta a una tabla (path). Cuando llamamos a un mtodo del cliente, estos datos son uno de los argumentos. A partir de aqu, la gestin es bastante similar a como se hace en base de datos, refirindome al concepto de queries, cursores Por tanto, tampoco vamos a exterdernos mucho en este punto, sino tan slo comentar las cosas bsicas y aportar los enlaces a ejemplos oficiales de cdigo. Para solicitar datos a un proveedor, necesitaremos construir una query. Para ver un ejemplo de una query simple, mi recomendacin es visitar este enlace. Modificar datos ser similar, pudiendo ver ejemplos en el siguiente enlace. Pero supongamos que no queremos crear nuestro propio Content Provider, sino que queremos rescatar ciertos datos del telfono para usarlos en nuestra aplicacin. Este es el caso del Calendar o los Contactos. Cada uno tendr su propio proveedor, de forma que podremos disponer de esta informacin en nuestra aplicacin, siempre y cuando le hayamos dado permisos en el Manifest. En el caso del Calendar utilizaremos el Calendar Provider y en el caso de los Contactos utilizaremos el Contacts Provider. Con esto, podremos relacionar nuestras aplicaciones mediante los Content Providers, as como utilizar datos externos a nuestra app como son los eventos de Calendario o los Contactos.
50
Esta funcionalidad fue aadida para Android HoneyComb 3.0, pero qu pasara si quisiramos poder utilizarla en una versin anterior de Android? Simplemente tendremos que utilizar la librera de soporte, por ejemplo la librera appcompat v7 support, en la cual nos basaremos para el resto del artculo. Para aadir el ActionBar, bastara extender nuestra actividad de la claseActionBarActivity (de la librera de soporte) y utilizar uno de los temasTheme.AppCompat como tema de nuestra actividad. En el caso de que no necesitemos esa compatibilidad, podremos utilizar la clase Activity normal y usar uno de los temasTheme.Holo. Para eliminar el ActionBar, bastar llamar el mtodo hide:
51
Tambin podemos aadir elementos de accin, de forma que las acciones ms importantes las veremos en todo momento en nuestro ActionBar, y las menos importantes las podemos ocultar en el botn overflow (los famosos tres puntos).
Para aadir un men de acciones, deberemos seguir los siguientes pasos: 1. Crear el men en la carpeta res 2. Sobreescribir el mtodo onCreateOptionsMenu 3. Para decidir si queremos mostrar siempre o slo si hay espacio el elemento de men, utilizaremos la propiedad showAsAction 4. Siempre tenemos que definir el ttulo (title) para cada elemento ya que: 4.1. Si no hay suficiente espacio, el elemento aparecer en el desplegable del elemento overflow slo con el ttulo 4.2. Las pantallas optimizadas para invidentes leern dicho ttulo 4.3. Si slo vemos el icono, al hacer un click largo con el dedo, veremos el texto
52
Una vez aadidos los elementos, basta con gestionar los eventos al hacer click sobre cada elemento de men:
Adems, podremos hacer uso del Split ActionBar, que bsicamente consiste en que si falta espacio se aada una segunda barra donde ya dispondremos de ms espacio. Para ello tendremos que aadir la opcin uiOptions = splitActionBarWhenNarrow a cada actividad declarada en nuestro Manifest o directamente a la aplicacin entera. Pero hay que tener en cuenta que esta opcin fue aadida en la API 14 de Android, y si queremos soportarlo en versiones anteriores, deberemos aadir un <meta-data> como hijo de cada actividad que declare dicho valor.
Otra cosa que podemos aadir en el ActionBar es que el icono de la izquierda (el icono de la aplicacin) nos permita navegar a la pantalla justamente superior. Para ello, deberemos llamar al mtodo setDisplayHomeAsUpEnabled. Otra opcin es declarar en el Manifest para cada actividad cul ser su actividad padre (slo disponible desde Android 16).
53
Ms cosas que podemos aadir y vemos en algunas aplicaciones son los cuadros de dilogo de bsqueda. Para ello utilizaremos un ActionView.
54
Tambin podemos aadir un Action Provider, como por ejemplo es el caso del tpico botn que podemos ver para compartir:
55
Otro elemento tpico son las pestaas, para las cuales necesitaremos: 1. Implementar la interfaz ActionBar.TabListener 2. Instanciar ActionBar.Tab para cada pestaa y asignar el escuchador con el mtodo setTabListener. Con setTitle y setIcon personalizaremos la pestaa. 3. Aadir cada pestaa al ActionBar a travs del mtodo addTab
Otro elemento que podemos aadir es una navegacin desplegable. Para ello: 1. Crearemos un SpinnerAdapter, el cual nos proporcionar la lista de elementos de la lista desplegable. 2. Implementaremos ActionBar.OnNavigationListener para definir el comportamiento que necesitamos para cada elemento 3. En el mtodo onCreate de nuestra actividad, habilitaremos la navegacin desplegable llamando a setNavigationMode(NAVIGATION_MODE_LIST) 4. Asignaremos el callback para la lista con setListNavigationCallbacks
Como ltimo paso, deberemos personalizar la ActionBar a nuestro estilo y al de nuestra aplicacin, mediante los estilos. Pero siempre os recomendar seguir las guas de estilo de Android. Si quieres ver algunos ejemplos de cdigo, sigue las lecciones que Google nos proporciona sobre ello aqu.
56