Reseña de “El gran libro de android”. 
lunes, enero 16, 2012 at 12:18PM
jtristan in El gran libro de Android, Reseñas Android, reseña

Vamos a ver detalladamente el contenido del libro de programación en Android, "El gran libro de Android". Si estás aprendiendo a programar en Android, echa un vistazo al contenido del libro, puede que te interese.

Título: El gran libro de android 
Autor: Tomás Gironés, Jesús
Editorial: MARCOMBO, S.A.
ISBN: 9788426717320


Como comentario anecdótico, en la portada del libro nos encontramos con la imagen de un iphone. No sé si se trata de un error garrafal de la editorial o una estrategia de marketing, pero desde luego, sólo hace falta buscar en google comentarios sobre el libro para ver que parece ser su característica más destacada. Sin embargo, dentro nos encontramos con 340 páginas donde se tratan una gran cantidad de temas relacionados con android que podemos necesitar en el desarrollo de nuestras aplicaciones, así que vámos a centrarnos en ello.

Capítulo 1. Visión general y entorno de desarrollo.

En este capítulo se nos presenta android, su origen y algunas de sus características, como que es una plataforma abierta o que trae una gran cantidad de servicios, como localización, mapas, navegador, reconocimiento de voz, ....

Recorre brevemente la arquitectura de android, viendo un poco cada uno de sus componentes, el núcleo de linux como base, el runtime de android (basado en la máquina virtual Dalvik), las librerías nativas (por ejemplo webkit para el navegador, media Framework para codecs de reproducción y grabación de audio y video, SQLite como motor de base de datos, SSL, para permitir la encriptación), el entorno de aplicación que nos proporciona una plataforma de desarrollo (con las views que nos permitirá crear la interfaz gráfica, resource manager para acceder a recursos que no están en el código, los content providers para compartir datos entre aplicaciones o la notification manager para poder mostrar alertas en la barra de estado) y finalmente las aplicaciones.


Como no puede faltar, tenemos la guía para la instalación de eclipse junto con el SDK de android y el plugin para eclipse ADT (Android Development Toolkit). Tanto la instalación como la configuración viene acompañada de su correspondiente imagen con lo cuál es muy sencillo seguir los pasos.

Para finalizar el capítulo, crearemos nuestro primer programa, viendo, qué nos ofrece cada una de las plataformas que existen, desde Cupcake (1.5) hasta Honeycomb (3.0). No llega a tratar Ice Cream (4.0).

Capítulo 2. Diseño de la interfaz de usuario.

En este capítulo vamos a ver, como es posible, crear la interfaz de usuario mediante código o mediante xml en los ficheros layout (recomendado, ya que siempre hay que tratar separar la parte de diseño de la parte lógica, además, de que su renderizado es igual de rápido que si lo hiciésemos por código). Siguiendo esta filosofía, android permite utilizar el fichero strings.xml, para poder separar los textos de nuestros controles, de forma que sea fácil llevar a cabo la internalización de la aplicación.

Todos los controles y recursos que utilicemos, se van a generar en la clase de android R.java, clase que nunca debemos modificar.

Para facilitarnos el diseño de nuestras interfaces, sin tener que modificar el xml directamente, android nos proporciona una herramienta para la edición visual de las vistas. Desde esta herramienta, arrastraremos las vistas y los controles para formar la pantalla. Además, podemos comprobar como quedaría nuestra vista en cualquier configuración, ya sea con orientación horizontal o vertical, en configuración regional, según la hora del día (nocturna o diurna) o aplicando un tema. Por ejemplo, pensando es las dos posibles orientaciones, es posible, que para que el diseño quede correcto, necesitemos crearnos varios layout. Debemos crearnos carpetas individuales para cada orientación o tamaño de la pantalla, por ejemplo, si queremos una vista para la orientación horizontal tendremos que añadir la carpeta res/layout-land, para pantallas pequeñas res/layout-small y para pantallas grandes res/layout-large, etc. No es necesario conocer el nombre de todas las carpetas que vamos a tener que crear, desde eclipse, podemos ir a Nuevo -> Otro -> Android -> Fichero android XML, y desde ahí accederemos a todos los calificadores posibles, creándonos la carpeta o el fichero con el sufijo necesario, pudiéndose concatenar varios sufijos, por ejemplo, para el idioma inglés y en horizontal.

Dentro de nuestra vista, para poder utilizar varios controles (como textos, cajas de texto, checkboxes, etc) tendremos que utilizar los componentes layout. Estos nos permiten agrupar y posicionar distintos controles. En el libro se muestran los más importantes con una imagen de como quedarían varios componentes dentro de él y el código del layout.xml. Entre ellos vemos el linearLayout (todos los elementos en una fila o columna), el tableLayout (los componentes en forma de tabla, todos en una fila hasta que añadamos otra), el RelativeLayout (todos en función de un componente), el absoluteLayout (indicaremos mediante coordenadas donde debe figurar cada componente) y el frameLoyout (los componentes utilizan todo el contenedor, estando unos encima de otros, permitiendo mostrarles u ocultarles mediante la propiedad visibility).

En este capítulo, comenzamos con la creación de la aplicación que vamos a desarrollar
durante todo el libro, el juego asteroides.

Vamos a ver, como se crean los menús, a través del xml y cómo llamarle desde nuestra actividad con el método onCreateOptionsMenu(Menu menu) y como recibir la opción seleccionada con el método onOptionsItemSelected(MenuItem item).

También se detiene en los estilos y los temas. Un estilo nos permite definir el formato de una vista, teniendo un comportamiento similar a los css. Simplemente, debemos crear el estilo en el fichero res/values/styles.xml y en la propiedad style de nuestro componente indicar el estilo que deseamos aplicar. Android ya trae una serie de estilos predefinidos. Un estilo, como hemos visto se aplicará a un componente individual o actividad, sin embargo, podemos aplicar el estilo a toda nuestra aplicación mediante un tema, indicando en el androidManifest el tema en el parámetro android:theme.

Una características que nos ahorrará bastantes líneas de código, son la creación automática de las preferencias. En android, podemos configurar el fichero res/xml/settings.xml indicando el nombre y el tipo de la preferencia (pudiendo incluso trabajar con listas, cuyos datos podemos almacenar en /res/values/arrays.xml. En nuestra actividad utilizaremos la propiedad addPreferencesFromResource para indicar la preferencia que queremos cargar y Android nos cargará la vista. Igualmente, android se encarga de la persistencia de los valores indicados en las preferencias, pudiendo, acceder nosotros a ellos mediante la clase SharedPreferences, a la que pasaremos, el fichero donde se han grabado las preferencias y el modo de acceso, por ejemplo MODE_PRIVATE.

Capítulo 3. Gráficos en Android.

Para poder seguir desarrollando la aplicación asteroides, es necesario ver el tema de los gráficos. Sin embargo, a mi modo de ver, quedan todavía muchos conceptos importantes de android, como para ver ahora esta parte. Teniendo en cuenta, que a priori, la inmensa mayoría de nuestras aplicaciones no van a tener que trabajar con gráficos.

En este capítulo, se nos presenta la clase Canvas, que representa el lienzo donde vamos a dibujar. Para dibujar, utilizaremos la clase Paint, mediante la cual indicaremos el color, el estilo y el grosor. Se nos comentan una serie de métodos de la clase Canvas, como por ejemplo drawCircle para dibujar círculos o drawText para dibujar textos.

Como ejemplo de lo visto en el capítulo, y para dotar de funcionalidad al juego, se creará una clase que nos permita desplazar cualquier gráfico por la pantalla.

Capítulo 4. Entradas en android: teclado, pantalla táctil y sensores.

Hemos visto en los capítulos anteriores como para crear nuestras interfaces gráficas, añadimos a una vista una serie de componentes. Para poder capturar las acciones del usuario en estos componentes tenemos los eventos. En android disponemos de dos formas, los escuchadores (event listener) y los manejadores (event handler).

Los escuchadores sólo tienen un método callback a registrar. Por ejemplo, onClick(), on FocusChange(), onTouch(), etc.

Se muestran las dos alternativas que tenemos para crearlos, mediante un objeto anónimo o implementando la interfaz. Aunque he visto en código mucho más la primera, parece ser que la recomendada es la segunda ya que tiene menos gasto de memoria.

 public class Ejemplo extends Activity implements OnClickListener{ 
  public void onClick(View view){
     ...
  }
}

Los manejadores responden a los eventos de entrada sin importar donde está el foco. Por ejemplo pulsar la pantalla, el botón de atrás. Los manejadores, nos permiten si heredamos la clase View, crearles directamente. Algunos serían onKeyDown(int KeyCode, KeyEvent e), para cuando una tecla es pulsada, su contrario onKeyUp(int keyCode, KeyEvent e), onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect), cuando se cambia el foco, etc.

El siguiente punto que vemos son los gestures, una característica que trajo Android en su SDK 1.6. Un gesture es un movimiento pregrabado en la pantalla, que nuestra aplicación puede reconocer. Google Gesture Search nos permitirá ver como funciona. Para crear nuestra propia librería de gestures, usaremos el Gesture Builder, que ya viene preinstalada en el emulador. Una vez creada la librería añadiremos a nuestra aplicación el fichero gestures que hemos creado anteriormente (en /res/raw). Tenemos un componente que nos permite introducir el gesto, el GestureOverlayView. Con el escuchador onGesturePerformed(GestureOverlayView ov, Gesture gesture) sabremos cuando se ha introducido un gesto. Finalmente con el método recognize sabremos a qué acción corresponde ese texto.

En este capítulo, también se tratan los sensores. Tenemos muchos tipos de sensores (todos vienen en la clase Sensor), como el acelerómetro (TYPE_ACCELEROMETER), el sensor de luz (TYPE_LIGHT) o el sensor de proximidad (TYPE_PROXIMITY). Para saber cuáles están disponibles en nuestro equipo usamos la clase SensorManager.

Para poder acceder a los valores del sensor primero tenemos que registrar el sensor con el método registerListener() de la clase SensorManager, donde le indicamos cada cuanto tiempo queremos recibir acutalizaciones. Para leer los datos tenemos que implementar la interfaz SensorEventListener, sobreescribiendo onSensorChanged(SensorEvent event). Con getType sabemos si estamos recibiendo el sensor que esperamos y con values obtenemos los valores. Finalizamos el capítulo, viendo como podemos implementar los sensores en nuestro juego. Se pretende manejar la nave mediante el sensor de orientación.

El capítulo finaliza, viendo como podemos implementar los sensores en nuestro juego. Se va a desarrollar el código para poder manejar la nave mediante el sensor de orientación.

Capítulo 5. Multimedia y ciclo de vida de una aplicación.

En el quinto capítulo vemos el ciclo de vida de una aplicación. Aunque pueda parecer un poco tarde para ver el ciclo de vida, creo que es un acierto el no introducirlo hasta que no tenemos unos conceptos de android. En android, el ciclo de vida de la aplicación la controla android, no nosotros, siendo él, el que en función de las necesidades de memoria y de nuestro estado de la actividad-servicio, decidirá si debe cerrar o no la aplicación. Disponemos de cuatro posibles estados:

  1. Activa (Running), la actividad tiene el foco, es visible.
  2. Visible (Paused): es visible, pero el foco está situado a otra actividad, que debe ser transparente o no ocupar toda la pantalla.
  3. Parada (Stopped): la actividad no es visible
  4. Destruida(Destroyed): cuando la actividad termina o es matada por android.

Por cada uno de estos estados, se generan una serie de eventos:

  1. onCreate(Bundle): cuando se inicializa la aplicación. Aquí se realiza la carga de la interfaz de usuario. Si la aplicación se reanuda podemos recibir información del estado anterior mediante la clase Bundle.
  2. onStart(): la actividad está a punto de mostrarse al usuario.
  3. onResumen(): la actividad comienza a interactuar con el usuario.
  4. onPause(): la actividad va a pasar a segundo plano, debemos aprovechar para almacenar datos o el estado de la interfaz.
  5. onStop(): la actividad ya no es visible.
  6. onRestart(): se vuelve a cargar la actividad habiendo pasado por onStop().
  7. onDestroy(): se llama antes de que la actividad sea destruida.

En el caso de encontrarnos con poca memoria, ni onStop(), ni onDestroy() tienen porqué ser llamadas.

En el capítulo también se detallan las prioridades que se asignan a los procesos a la hora de eliminarlos:

  1.  Proceso de primer plano (Foreground process): es el último en eliminarse. La pantalla está visible y ha pasado por onResume() con lo que el usuario está ya interactuando.
  2. Proceso visible (Visible process): para actividades visibles pero sin foco (onPause() ha sido llamado).
  3. Proceso de servicio (Service process): para los servicios.
  4. Proceso de fondo (Background process): una actividad que ya no es visible (se ha llamado al método onStop(). Suelen ser fácilmente eliminados.
  5. Proceso vacío (Empty process): se utiliza como caché para mejorar la carga de componentes.

Como hemos visto, nuestra actividad puede pasar a no estar visible (al llamar al método onStop()), por ejemplo, porque hayamos abierto el navegador, google maps, etc y después queremos que vuelva a renaudarse. Al pasar a no visible, puede que la actividad sea destruida, con lo cual, deberíamos de guardar los datos, su estado, para que en el caso de que se vuelva a cargar, podamos mantener el mismo estado. Si bien podemos aprovechar el método onPause() para guardar los datos en un fichero, base de datos, o cualquier otro mecanismo de persistencia, android nos proporciona un mecanismo para almacenar este estado y volver a cargarlo. El único problema es que no necesariamente el sistema va a llamarles, sobre todo en casos de extrema falta de memoria. Los métodos son:

  1. onSaveInstanceState(Bundle): guarmaos el estado.
  2. onRestoreInstanceState(Bundle): recuperamos el espado guardado.

Una vez visto el ciclo de vida de las aplicaciones, el resto del capítulo se dedica al tema multimedia. Se explican las principales clases de android como son:

El libro contine una tabla con todos los formatos soportados por android. Es un punto que no entiendo, y que veo en varios temas del libro. En algunos casos no se llega a entrar un poco más a detalle y sin embargo, aquí se recopila esta información, que al menos que vayamos a hacer multimedia muy específico, no es necesario.

En el resto del capítulo, vamos a ver ejemplos de como reproducir un video con VideoView o cómo reproducir un sonido de fondo con MediaPlayer y finalmente como crearnos un reproductor multimedia paso a paso.

Capítulo 6. Seguridad y funcionamiento.

Este capítulo es muy importante, ya que para muchas de las acciones de nuestra aplicación necesitaremos permiso del usuario.

En android cada aplicación crea una cuanta de usuario Linux, de forma, que no podamos acceder a recursos de otras aplicaciones que tengan otro usuario. Cuando creamos un fichero, podemos asigarle los modos: MODE_WORLD_READABLE y/o MODE_WORLD_WRITEABLE para permitir que otras aplicaciones puedan leer o escribir en los mismos. Si queremos que varias aplicaciones compartan el mismo proceso, debemos asignarles el mismo usuario. Lo podemos hacer desde el parámetro sharedUserId del AndroidManifest.xml.

Si queremos acceder a ciertos recursos a características del hardware, tenemos que solicitar permiso al usuario cuando este instala la aplicación. En el androidManifest, con la etiqueta indicaremos el nombre del permiso que deseamos solicitar. Por ejemplo ACCESS_FINE_LOCATION para poder obtener la localización basada en GPS o SEND_SMS para mandar SMS. También podemos crear nuestros propios permisos utilizando la etiqueta .

En el capítulo también vemos otra importante característica de android, y que nos va a permitir desarrollar aplicaciones muy interesantes para el usuario, como es la localización.

La localización podemos efectuarla mediante gps o mediante la información de las torres de telefonía o puntos wifi. Para poder acceder a ellas necesitamos los siguientes permisos ACCESS_FINE_LOCATION y ACCESS_COARSE_LOCATION respectivamente.
Para acceder a la localización utilizamos la clase LocationManager y con el método getBestProvider(criteria, true), vemos cuál es el mejor proveedor disponible.

Podemos indicarle un criterio de selección basado en la potencia, la precisión, ...
Con requestLocationUpdates() indicamos al sistema que nos notifique los cambio de posición y con removeUpdates() paramos el servicio (este deberíamos usuarle en onPause() para evitar que se siga mandando información a la aplicación cuando no esté activa. Para poder responder a eventos de localización disponemos de la interfaz LocationListener. El evento onLocationChanged se activará cada vez que se cambie de posición. Con el evento onProviderDisabled sabemos que se ha permido la conexión (por ejemplo podemos utilizarlo para tratar de buscar otro proveedor).

Tratando la localización, una de las herramientas más útiles y comunes de uso es google maps. Si queremos utilizarlo tendremos que solicitar dos claves de registro, una para el desarrollo y la otra para la publicación.

Para usar google maps tenemos que añadir la librería a la aplicación, para ello, en el androidManifest indicaremos en "Uses library" “com.google.android.maps”. Así mismo, además de los permisos de localización necesitaremos el de acceso a internet “android.permission.INTERNET”. Al crear nuestra actividad utilizaremos la actividad propia de maps, MapActivity y añadiremos el componente MapView.

Para posicionarnos en un punto mediante coordenadas lo haremos en el escuchador onLocationChanged(Location location) con el método setCenter(point).

Finalizamos el capítulo viendo como podemos fragmentar un asteoride cuando es alcanzado con un misil. En este punto, creo que estamos tratando de finalizar el juego sin que tenga nada que ver con el contenido del capítulo. Creo que sería mejor, dedicar un capítulo para aquellas partes del juego que no pertenecen a ningún punto en concreto del libro y de esta forma mantener un poco más la organización.

Capítulo 7. Almacenamiento de datos.

En este capítulo vamos a ver distintas formas para hacer que nuestro datos persistan. Se prueban todas ellas almacenando en nuestro juego asteroides las puntuaciones.

La primera de estas formas es el sistema de ficheros. En android podremos almacenar los ficheros en la memoria interna del teléfono o en nuestra tarjeta sd. Como ya se vió en un capítulo anterior, los ficheros, por defecto, sólo son accesibles por la aplicación, ya que cada aplicación crea una cuenta de usuario linux. Para trabajar con ficheros podemos utilizar el paquete estandar “java.io”. Android incorpora métodos adicionales para facilitarnos el trabajo con los ficheros, en la memoria interna, como son openFileInput() y openFileOutput() de la clase Context. Estos métodos, dan por supuesto, que el fichero se encuentra en la ruta /data/data/nombre_del_paquete/files/. Para acceder a la tarjeta sd tenemos que usar la ruta /sdcard/... y es necesario declarar el permiso WRITE_EXTERNAL_STORAGE.

La segunda forma sería acceder a ficheros de recursos. Estos van directamente en el paquete de la aplicación, en la carpeta res/raw (que es la única que nunca va a ser compilada. Sin embargo, estos ficheros no son modificables.

También, podremos utilizar xmls para almacenar información o recuperarla. En el libro se analizan dos librerías SAX y DOM (Document Object Model). SAX es recomendada para un análisis rápido y un uso mínimo de memoria. Tenemos que crearnos una estructura de datos para almacenar los datos. SAX nos proporciona cinco métodos, que heredan de la clase DefaultHandler, para el procesamiento del XML:

Para escribir el XML mediante SAX utilizamos la clase XMLSerializer, con los métodos startDocument, startTag,attibute, starText, enDocument,endTag,...

Con DOM vamos a cargar todo el documento en memoria, creando o modificando directamente nuevos nodos, aunque es más lento que SAX.

El capítulo contiene dos completos ejemplos tanto de lectura como de escritura con SAX y DOM.

Otra forma de persistencia es almacenar datos en una base de datos. Android incorpora el motor SQLite. Para crear la estructura de la base de datos tenemos que sobreescribir los métodos onCreate(), onUpgrade() y a veces onOpen() de la clase SQLiteOpenHelper. Con el método getReadableDatabase() llamamos a esta clase y creamos la estructura. Para recuperar datos, podemos utilizar el método query de SQLiteDatabase que les devuelve en un objeto Cursor y para insertar datos tenermos el método execSQL que nos permite añadir una consulta, en este caso de tipo INSERT INTO.

Por último, se analizan los ContentProviders como forma de poder acceder a información de otras apliaciones o compartir la nuestra. Por ejemplo, android ya trae el acceso a los contactos del teléfono, al historial de llamadas o a las preferencias del sistema.

Todo ContentProvider tiene que estar identificado por una URI, por ejemplo, content://call_log/calls, que nos permitirá acceder al historial de llamadas. Si queremos acceder a un registro en concreto, tenemos que identificarle (content://call_logs/calls/8 para acceder a la 8 llamada). Cada ContentProvider tiene una constante con su correspondiente URI con lo cual no es necesario conocer estas. Para leer información, primero analizaremos el URI mediante el método Uri.parse(URI) y después usaremos el método managedQuery de la clase Activity que nos permite construir una consulta contra ese conjunto de datos, que son devueltos en un Cursor.

Para escribir información en un ContentProvider, simplemente, debemos almacenarlos como pares clave-valor en un objeto ContentValues e insertarlos con el método getContentResolver().insert(URI, valores). Al igual que disponemos del método insert, también tenemos el método delete para poder eliminar regristros y update para su actualización.

Si queremos que nuestra aplicación comparta datos para que otras aplicaciones hagan uso de ellos, podemos crearnos nuestro propio ContentProvider. Para ello debemos extender la clase ContentProvider, implementando los métodos getType(), devuelve el MIME de los elementos, query(), para realizar consultas, insert(), delete() y update(). Deberemos declararnos la URI mediante el método Uri.parse y para identificar los distintos tipos de URIS añadimos cada una con la clase UriMatcher.

El primer método que debemos sobreescribir es getType para que nos devuelve el tipo MIME. Un MIME está compuesto por dos partes tipo_genérico/tipo_específico (text/html), por convenio, en un ContentProvider, si es un recurso único utilizamos "vnd.android.cursor.item/vnd.ELEMENTO" y si es una colección "vnd.android.cursor.dir/vnd.ELEMENTO". Reemplazamos ELEMENTO por el identificador que describa nuestro tipo de datos, por lo general será el paquete de la aplicación.

Sólo nos quedan los métodos de tratamiento de datos, query, donde si trabajamos con una base de datos podemos usar la clase SQLiteQueryBuilder para crearnos la consulta que nos devuelva todos los elementos o sólo uno (con appendWhere podemos añadir la condición _id), insert, update y delete (con los métodos que ya se vieron en el punto de la base de datos).

Para que el contentProvider forme parte de nuestra aplicación deberemos añadirle al AndroidManifest mediante la etiqueta provider.

En este capítulo también se ve la comunicación entre actividades. Para llamar a otra actividad tenemos que declararnos un Intent, indicándole la actividad que deseamos abrir (Intent intent = new Intent(this, CLASE_ACTIVIDAD.class); Si queremos pasar además algún valor debemos utilizar el método putExtra. Con el método startActivity(intent) hacemos la llamada. a la nueva actividad. Para recoger los valores recogeremos los parámetros en un objeto Bundle con el método getIntent().getExtras().

También, es posible, que nuesta segunda actividad, devuelva información a la actividad qeu la llamó una vez que finalice. Para ello debemos utilizar el método startActivityForResult(intent, valor) para llamar a nuesta segunda actividad y sobreescribir el método onActivityResult. Finalizaremos nuestra segunda actividad mandando el resultado con el método setResult() y finalizando la actividad con finish().

Capítulo 8. Internet: sockets, HTTP y Servicios web.

En este capítulo vamos a ver como podemos mandar o recuperar información de la web. Se mostrarán como funcionan diversas alternativas utilizando la funcionalidad de almacenar la puntuación obtenida en el juego asteroides.

En primer lugar vemos los sockets, que son una forma de comunicar dos programas mediante el protocolo TCP/IP. Un socket se define por una dirección IP más un número de puerto, lo cual nos permite ejecutar diferentes programas que accedan al mismo servidor.

Podemos usar los sockets stream (TCP), que permiten transmitir datos de forma continua, obligándonos a establecer una conexión. Estos gestionan el control de errores, es decir, si parte de la información no llegó al destino, volverá a ser transmitida.

Los sockets datagram (UDP) nos permiten mandar información en paquetes de tamaño limitado sin necesidad de usar una conexión. Sin embargo, no tienen control de error, por lo que es más adecuado utilizar los sockets stream.

Para crearnos un socket utilizaremos la clase Socket, indicándole la dirección IP y el puerto. Con sus métodos getInputStream() y getOutputStream() recuperaremos o enviaremos los datos.

La segunda forma que nos muestra el capítulo de conexión con la web es el protocolo HTTP. Este protocolo utiliza el puerto 80. En la versión 1.0 tenemos disponibles los métodos GET para solicitar la lectura de un recurso, POST para el envío de información asociada a un recurso del servidor, PUT para crar un nuevo recurso, DELETE, para eliminarle y HEAD para mandar sólo la cabecera y no la página. Para utilizar este protocolo en android disponemos de las librería “java.net” o “org.apache.commons.httpclient”.

La última opción que trata el libro son los servicios web. De las opciones que existen la que deberíamos de usar con android es REST (Transferencia de Estado Representacional), con lo que se utiliza diréctamente el protocolo HTTP, con sus operaciones GET,POST,PUT y DELETE. En los REST utilizamos una URI como identificador del recurso. Debido a su simplicidad supone menos sobrecarga para el cliente.

Se muestra un ejemplo de como podemos utilizar un servicio REST ya existente, en este caso el servicio de búsqueda de Yahoo. Después también se ve como crearnos nuestro propio servico REST, viendo como se crean desde eclipse. Finalmente vemos como utilizar el servicio web creado desde Android. Para ello tenemos que crearnos el objeto URL con el identificador del servicio web. Después estableceremos la conexión mediante la clase HttpURLConnection. Como la información en este caso es devuelvta en formato XML tendremos que utilizar un objeto de la clase SAXParser para descodificarla.

Capítulo 9. Servicios y notificaciones.

Utilizaremos los servicios en android como la forma de ejecutar una tarea en segundo plano (startService()) o para comunicar nuestra aplicación con otra (bindServide()).

Cuando creamos un servicio con startService() el sistema llama primero al método onCreate() y después a onStartCommand(), si volvemos a llamar al servicio, este no se crea de nuevo, con lo cual no vuelve a llamar a onCreate() pero si pasará por onStartCommand().

Mediante stopService() o stopSelf() paramos el servicio y se llamará al método onDestroy(). El servicio puede detenerse antes de que nosotros lo hagamos, en situaciones de baja memoria, en función del valor que devolvamos en el onStartCommand() el sistema intentará volver a crear el servicio (START_STICKY) o sólo se creará si hay una nueva solicitud (START_NOT_STICTY).

Si queremos conectarnos a un servicio utilizaremos bindService(Intent servicio, ServiceConnection conexion, int flags). En este caso, después de onCreate() se llamará al método onBind(Intent intento) que devolverá un objeto IBinder para establecer la conexión del servicio con el cliente. Para poder efectuar la comunicación habrá que escribir una interfaz AIDL (Android Interface Definition Language).

Para crear esta interfaz, debemos conocer algunas de las características de AIDL. Los parámetros que acepta son los tipo primitivos, String, CharSequence, List, Map, una interfaz AIDL o un objeto Parcelable. Para los parámetros no primitivos hay que indicar si van a ser parámetros sólo de entrada (in), sólo de salida (out) o de entrada y salida (inout). Los primitivos siempre son de entrada. El fichero de la interfaz tiene que tener como extensión aidl para que eclipse genere automáticamente la clase.

Es necesario declarar el servicio en el androidManifest, indicando con el atributo process que va a estar en un proceso independiente de la aplicación.

Finalmente,para llamar a la interfaz remota deberemos declararnos un objeto del tipo de nuestra interfaz. Implementaremos la clase ServiceConnection, que nos permite saber cuando nos conectamos (onServiceConeected()) o cuando nos desconectamos (onServiceDesconected()). Nos conectaremos al servicio al llamar al método bindService. Para desconectarnos utilizamos el método unbindService().

Aunque el capítulo está decidado principalmente a los servicios, también se ven las notificaciones, ya que es la forma lógica que dispone android para que los servicios puedan mostrar información al usuario.

Para usarlas, necesitaremos obtener una referencia al NotificationManager. Después tendremos que crearnos el objeto Notification. Le indicamos el icono que deseamos mostrar, el mensaje y cuando queremos que se visualice. Finalmente, pasaremos la notificación creada al NotificationManager con el método notify. Si queremos eliminar una notificación disponemos del método cancel.

A nuestras notificaciones podemos asociarlas un sonido (Notification.DEFAULT_SOUND), añadirle vibración(Notificacion.DEFAULT_VIBRATE) o añadirle un parpadeo de LED (Notification.DEFAULT_LIGHTS).

Capítulo 10. Gráficos 3D con OpenGL.

Llegamos al último capítulo pues el siguiente, lo podríamos considerar como un apéndice, ya que no trata un tema en concreto sino que nos da unos consejos a la hora de publicar nuestra aplicación y nos indica como empaquetarla.

Este capítulo, es muy amplio, ya que se trata con bastante detalles bastantes características de OpenGL. Se realizan ejemplos con todas ellas pero no se aplica nada al juego asteroides. Son ejemplos exclusivos para ver como podemos ir construyendo nuestras formas e ir dotándolas de cualidades.

OpenGL ES es una versión reducida diseñada para dispositivos móviles. En el libro se muestra como trabajar con primitivas y colorearlas mediante un array. También se detalla la clase GlSurvaceView que es la superficie donde vamos a dibujar. Se representará un cubo, como definir un punto de vista, iluminación, situación de luces, aplicación de texturas, etc.

Capítulo 11. Publicar aplicaciones.

Y llegamos al último capítulo. Como he comentado en el capítulo anterior, aquí vamos a ver una serie de consejos para que nuestra aplicación pueda alcanzar más mercado y los pasos a seguir a la hora de generar el apk de nuestra aplicación.

A la hora de publicar, debemos de elegir la mínima versión de SDK ya que esto nos hará llegar a más dispositivos. Igualmente, deberemos de internacionalizar los textos, para lo cual, como ya hemos visto en uno de los primeros capítulo tenemos el fichero strings.xml.

El diseño es muy importante y a la vez un punto complicado, pues en el mercado nos vamos a encontrar con muchos dispositivos que tengan diferentes versiones de pantalla, resolución o densidad. Una característica que nos provee, en especial a partir de la versión Honeycomb es que no sólo vamos a poder trabajar para móviles, sino que podemos realizar aplicaciones para tabletas, ordenadores e incluso televisiones. En este capítulo nos muestra las divisiones de pantalla que existen ,por ejemplo, small (2 -3,5 pulgadas) o large (son para tabletas con un tamaño de entre 4,2 y 7 pulgadas) o la densidad (ldpi para entre 100 y 130 dpi o hhdpi entre 260 y 340 dpi).

Opinión.

Como podéis ver estamos ante un libro en el que se tratan todos los temas de android que vamos a necesitar para poder desarrollar cualquier tipo de aplicación, ya sea sencilla o compleja, utilizando localización, sensores, conexión web, servicios, multimedia, … Contiene una gran cantidad de información, tratando ciertos temas con detalle.

Además, las explicaciones son muy claras y los ejemplos al no ser excesivamente complejos permiten apoyar rápidamente el tema tratado.

Como notas negativas, hay algunos temas que no se tratan suficientemente como pueden ser los intents. Aunque también es cierto, que no hay libro que pueda tratar en profundidad todo lo que nos provee android. Para ello, como se comenta en el libro no nos queda más remedio que utilizar la documentación de google.

La última nota negativa, que nada tiene que ver con el excelente contenido del libro, es la maquetación. Creo que las editoriales españolas deberían de esforzarse un poco más en este tema para poder presentar el libro con un diseño mínimo.

Article originally appeared on javaHispano (http://www.javahispano.org/).
See website for complete article licensing information.