Después de haber aprendido la estructura de un proyecto Android y de haber hecho nuestra primera aplicación, vamos ahora a ponernos con cosas un poquito más serias. En esta tercera entrada, propondremos la realización de una aplicación que haga una búsqueda de las redes Wifi que tenemos a nuestro alrededor y que nos muestre sus parámetros, como por ejemplo el ssid y qué seguridad utilizan. La aplicación resultante debe tener la siguiente apariencia.
Nos ponemos manos a la obra y creamos un proyecto en Android cuyo nombre sea Ejercicio2, como paquete com.fluproject.Ejercicio2, su target Android 2.2 y no nos olvidamos de indicarle que queremos una clase principal llamada Main (si alguien no recuerda como se hace todo este proceso que le eche un vistazo a las dos entradas anteriores).
Diseñando la interfaz de la actividad Main:
Una vez tenemos nuestro proyecto creado nos vamos a poner a modelar la interfaz de la aplicación. Vamos a empezar por la primera actividad (clase Main) que, tal y como observamos en la imagen anterior, tendrá como elementos una imagen (ImageView) y un botón con funcionalidad (Button). Lo primero que debemos hacer es meter las imágenes del archivo resources, que os adjuntamos en la entrada, a la carpeta /res/drawable-hdpi/. Vamos ahora al fichero que define la interfaz de nuestra actividad Main main.xml y lo dejamos con esta pinta:
Como podemos ver en el código del main.xml, tenemos un LinearLayout principal que contendrá la imagen del banner de fluproject y otro LinearLayout. El segundo LinearLayout contendrá un TextView con el texto "Escanea Wifi" y un Button con forma de imagen. El motivo de separar la interfaz en dos LinearLayout es conseguir darle gravedad sólo al segundo LinearLayout (android:gravity="center") de forma que sólo se centren en la pantalla el TextView y el Button. Una vez definida la interfaz, pasamos ahora a darle lógica.
Definiendo la funcionalidad de la actividad Main:
La funcionalidad de esta actividad es bastante sencilla, exactamente igual que la que utilizamos el otro día para nuestra primera aplicación. La única diferencia es que aquí, además de mostrar un mensaje de texto, crearemos una nueva actividad y la mostraremos. A modo de recordatorio, las actividades (Activity) se corresponden con las pantallas que tendrá nuestra aplicación. En la navegación por pantallas, Android trata las actividades mediante una pila de actividades, de forma que siempre estaremos visualizando la actividad superior de dicha pil, la que se encuentre en la cima. Cuando arranca una nueva actividad siempre se pone en la cima de la pila, en primer plano. Cuando pulsamos el botón 'atrás' estaremos realizando una acción equivalente a 'desapilar' , cerraremos la actividad actual y mostraremos la actividad que esté en la cima de la pila. Si no hay ninguna actividad más, saldremos de la aplicación.
Volviendo a la lógica de la actividad Main, tendremos una clase Main.java con esta apariencia:
Como vemos implementamos de OnClickListener para escuchar eventos del Button que hemos definido para escanear. En el método onClick vemos que al pulsar el Button (con id button1 en nuestro main.xml) sacamos una alerta textual por pantalla con contenido "Escaneando redes wifi..." y que además creamos una nueva actividad por medio de la clase Intent:
Intent wifiList = new Intent(this, Wifilist.class);startActivity(wifiList);
Al constructor de la clase Intent, clase responsable de crear la nueva actividad, le indicamos la actividad origen y la actividad destino que queremos que se muestre a continuación, que será la actividad Wifilist, la cual todavía no hemos definido ni como actividad ni como clase. Para definir la actividad Wifilist tenemos que crearnos una nueva actividad que se compondrá de una clase Wifilist.java y de un fichero xml wifilist.xml (por convenio de nombres vamos a intentar siempre llamar a la clase de la actividad y a su fichero xml igual, salvo que la primera letra del nombre de la clase será mayúscula y la primera letra del nombre del fichero xml será minúscula):
- Creamos una nueva clase en nuestro paquete com.fluproject.Ejercicio2 de la siguiente forma: Botón derecho del ratón sobre el paquete, New - > Class, en SuperClass escribimos android.app.Activity , le damos un nombre Wifilist y a aceptar. Una vez creada, pinchamos con el botón derecho del ratón sobre la clase, Source -> Override/Implement Methods y seleccionamos el método onCreate(Bundle).
- Una vez creada la clase creamos su fichero wifilist.xml, para ello nos vamos a la carpeta /res/layout pulsamos el botón derecho del ratón y seleccionamos New->Android XML File, le damos como nombre wifilist y finalizamos.
- Una vez creada la actividad debemos definirla en el fichero AndroidManifest.xml. Abrimos dicho fichero, nos vamos al apartado Application y bajamos a la sección Application Nodes. Ahí podemos observar como tenemos solamente una actividad declarada, la actividad Main. Para declarar la actividad Wifilist pulsamos Add... -> Activity y rellenamos sus propiedades a la derecha. Sólo pondremos el nombre de la actividad Wifilist y comprobamos que se cambia en el cajetín de Application Nodes.
Diseñando la interfaz de la actividad Wifilist:
Como pudimos observar en la imagen del principio, nuestra segunda pantalla tendrá una lista con todas las redes wifi que nuestro móvil haya encontrado. Luego el fichero xml que define la actividad Wifilist wifilist.xml tendrá la siguiente apariencia:
Como podemos observar tiene un LinearLayout con un único componente ListView.
Cada elemento de la lista también debe tener un aspecto, en nuestro caso no van a ser elementos simples, como podemos observar en la imagen del principio tendremos más de un elemento en cada item de la lista (ssid y seguridad), además estos elementos varían en tamaño y en color luego habrá que hacer otro proceso de definición antes de ponernos con la lógica. Este proceso pasa por definirnos otro fichero xml, de la misma forma que nos definimos el anterior, que contendrá el aspecto de cada item de la lista, el fichero se llamará elementitems.xml y tendrá este aspecto:
Como podemos ver, disponemos de un LinearLayout que alberga dos TextView, el primero hace referencia al ssid de la red y el segundo a la seguridad que tiene configurada. Y con esto ya tendríamos diseñada la interfaz de nuestra actividad Wifilist.
Definiendo la funcionalidad de la actividad Wifilist:
Lo primero que vamos a hacer para definir la funcionalidad de Wifilist es crearnos una clase básica en Java llamada Element. Como hemos dicho anteriormente nuestra lista no va a contener items simples sino que contendrá items compuestos por dos TextView, esto debemos modelarlo en una clase. La clase Element estará ubicada en el paquete com.fluproject.Ejercicio2 y tendrá la siguiente apariencia:
En la clase Element tendremos dos atributos uno será title que hará referencia en un futuro al SSID de la red, y el otro subtitle que hará referencia a la seguridad de la red. Además tendremos dos métodos para obtener tanto el atributo title como el subtitle.
A continuación, vamos a intentar explicar el código que debe tener la clase Wifilist.java en tres partes para intentar aclarar la funcionalidad.
Empezaremos nuestro código Wifilist.java definiendo tres atributos de clase: nets -> array de objetos Element que se encargará de guardar las redes descubiertas y posteriormente pasarle la información a un ArrayAdapter para que la lista pueda ser construida; manWifi -> Objeto de la clase WifiManager que nos permitirá acceder a la interfaz Wifi de nuestro dispositivo móvil y utilizar su funcionalidad; wifiList -> Objeto de la clase List donde guardaremos los Strings en bruto resultado de un escáner wifi.
Punto 1: En este punto llamamos a la interfaz wifi de nuestro dispositivo móvil y guardamos el resultado en el atributo manWifi. Posteriormente realizamos el escáner de redes mediante el método startScan() de la clase WifiManager y por último guardamos el resultado en bruto en nuestro atributo wifiList por medio del método getScanResults().
Punto 2: En este punto vamos a parsear la información que nos interesa del resultado del escáner guardado en bruto en el atributo wifiList. Recorreremos la lista wifiList, rescataremos la información que nos interesa de cada red (ssid y security) e iremos creando objetos Element y guardándolos en nuestro atributo nets. Una vez parseada y guardada toda la información resultante del escáner cargaremos a nuestra actividad la interfaz correspondiente wifilist.xml. Después crearemos un array adaptador AdapterElements de objetos Elements para nuestra lista que definiremos en el Punto 3.
Punto 3: Nos definimos una clase llamada AdapterElements que herede de ArrayAdapter. Esta clase nos va a servir para construir nuestra lista a partir del atributo nets. Esta clase tendrá un sólo atributo context que indicará el contexto donde se va a construir la lista, en la actividad presente. Como podemos observar AdapterElements tiene un constructor de clase que llama a su clase padre ArrayAdapter y un método getView. El método getView es el que se encarga de visualizar los elementos del atributo nets en forma de ListView. getView será llamado tantas veces como posiciones tenga nuestro atributo nets, además getView nos proporciona un parámetro position que nos servirá de índice para obtener toda la información de nets. Dentro de getView formamos nuestro item cargando el fichero elementitems.xml mediante el método inflate de la clase LayoutInflate, después sólo manipulamos el contenido textual de los TextView en función del valor de nets y listo!
Ya tenemos nuestra aplicación completamente diseñada, sólo nos queda un pequeño detalle, decirle al AndroidManifest.xml que nos deje utilizar el wifi de nuestro dispositivo móvil. Para ello nos vamos al fichero y añadimos los siguientes permisos tal y como explicamos en la entrada anterior:
android.permission.ACCESS_WIFI_STATEandroid.permission.CHANGE_WIFI_STATE
Esperamos que os haya gustado y os animamos a seguir, a preguntarnos todas las dudas que tengáis y a criticarnos (siempre de forma constructiva claro :D ) , si conseguís hacer y comprender este ejercicio estaréis ya a un nivel muy aceptable para programar aplicaciones en Android. ¡Un saludo!
===============================================================
Curso de introducción a Android (Instalación del Android SDK + Hello World)
Curso de introducción a Android II (Creando nuestra primera aplicación)
Curso de introducción a Android III (Escáner de redes WIFI)
Curso de introducción a Android IV (Crackeando redes Wifi)
===============================================================