viernes, 2 de marzo de 2012

Aplicación WiFi para Android

Android por ser open source proporciona para su desarrollo acceso a software para su uso como son el bluetooth y wifi ahora explicare como se utiliza las clases necesarias para conectar nuestro dispositivo android por wifi con algun otro que tambien lo utlize.

El paquete android.net.wifi provee los mecanismos por los cuales una aplicación Android puede acceder a la pila Wifi del sistema. La información que proporcionan las clases contenidas en android.net.wifi va desde los puntos de acceso detectados hasta el estado de la propia conexión, como pueden ser la velocidad, calidad del enlace, estado del sistema y un largo etcétera.
Además, el paquete también proporciona los métodos necesarios para escanear el entorno, iniciar y detener conexiones, configurar nuevas conexiones, y en general cualquier operación relacionada con la gestión de las conexiones del sistema.
El presente capítulo no es una descripción exhaustiva del manejo de las clases relacionadas con la comunicación WIFI, sino un resumen de las clases involucradas en el manejo del sistema WIFI y de sus capacidades.
Para una descripción detallada de todas las clases que se mostrarán a continuación, consúltese la Guía de Referencia de Android.
WifiManager
Es el punto de entrada a los servicios WIFI del sistema. Para obtener una instancia de la misma hay que pedirla al contexto de la aplicación (Context.getSystemService(Context.WIFI_SERVICE)). Ésta clase es única para todo el sistema y entre sus capacidades están las siguientes:
Permite acceder a la lista de redes configuradas tanto para consultarla como para modificarla permitiendo además editar parámetros concretos de cualquier configuración.
Se puede acceder a la conexión actual (si la hay). Puede iniciar una nueva conexión, detenerla y obtener información dinámica sobre el estado de la conexión.
Proporciona mecanismos para escanear el entorno en busca de Puntos de Acceso, dando toda la información sobre el mismo (tipo de encriptación, potencia, nombre, MAC, etcétera).
Proporciona un conjunto de Intents necesarios para implementar Broadcasts ante cualquier cambio de estado en la WIFI.
ScanResult
Contiene información relativa a los dispositivos descubiertos durante un escaneo del entorno. Por cada nuevo dispositivo se devolverá una instancia de ésta clase que lo representará. Sus campos, todos públicos, proporcionan la siguiente información
String BSSID: Dirección del Punto de Acceso.
String SSID: Nombre de la Red.
String capabilities: Describe el tipo de autenticación, la encriptación y la gestión de claves soportadas por el Punto de Acceso.
int frequency: Frecuencia en MHz del Punto de Acceso.
int level: Nivel de intensidad de la señal en dBm.
WifiConfiguration
Clase encargada de representar una configuración WIFI válida. Todos sus campos son públicos y proporcionan la siguiente información
WifiConfiguration.Status
Clase encargada de describir el estado de la conexión WIFI activa.
Para poder acceder a la API WIFI es necesario declarar los siguientes permisos en el manifest de nuestra aplicación:
  • ACCESS_WIFI_STATE permite acceder a la información sobre el estado de la WIFI y de todo lo relacionado con ella (conexiones, Puntos de Acceso configurados y/o detectados, etcétera).
  • CHANGE_WIFI_STATE permite cambiar todas las opciones relacionadas con la WIFI.
En el siguiente fragmento de código se puede ver la declaración de los citados permisos en el manifest:

Una vez que tenemos acceso al sistema WIFI de nuestro dispositivo, ya podremos llevar a cabo el escaneo. Antes de hacer ninguna operación es aconsejable asegurarse de que el sistema WIFI está activado. Si es así se puede comenzar a escanear. En caso contrario, habrá que esperar a que se active.

La función startScanning() comprueba el estado de la WIFI invocando a _wifiManager.isWifiEnabled(). Si la WIFI está desactivada mostrará un mensaje por la pantalla y retornará. En caso contrario, nuestra aplicación adquirirá la radio WIFI (_wifiLock.acquire()) y ésta quedará activada aunque dejemos de usar la aplicación durante un rato (en realidad, en éste caso no es necesario, pero se hace para que resulte ilustrativo).
Una vez que se ha adquirido la WIFI se inicia el escaneo con _wifiManager.startScan().
Recibiendo Intents
Android generará broadcasts intents para notificar cualquier cambio en el sistema WIFI. Los intents que nos pueden interesar a nosotros sonWifiManager.SCAN_RESULTS_AVAILABLE_ACTION, que nos notifica cuando ha finalizado un escaneo yWifiManager.SUPPLICANT_STATE_CHANGED_ACTION, que informa de que se ha producido un cambio en el estado de la WIFI.


En caso de que el intent recibido corresponda a SCAN_RESULTS_AVAILABLE_ACTION significará que el escaneo ha finalizado y que se puede leer el resultado (invocación a _wifiManager.getScanResults()).
El tipo de retorno de getScanResults() es List<ScanResult>. Se devolverá un ScanResult por Punto de Acceso detectado, del que podremos leer las propiedades como puede verse en el siguiente fragmento. En él se obtiene el SSID y el RSSI (atributo ScanResult.level) de los objetosScanResult que hay en un List para procesarlos posteriormente.


Si el intent recibido es SUPPLICANT_STATE_CHANGED_ACTION significará que se ha producido algún cambio en el estado de la WIFI. En el caso concreto de nuestra clase, interesa saber si la WIFI se ha activado o desactivado. intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,1)aportará información extra sobre el intent, del que podremos deducir si el cambio de estado ha sido o no el que nos interesa a nosotros. Si es así se realiza el proceso necesario, como puede verse en fragmento de código mostrado anteriormente.

Destructor de la clase

En nuestra clase se ha obtenido un bloqueo para la WIFI que la mantendrá encendida hasta que dicho blqueo no desaparezca. En éste caso es importante no olvidar desbloquear la WIFI, ya que de lo contrario ésta podría quedar encendida indefinidamente agotando la batería en poco tiempo. Lo mas aconsejable para ello es forzar el desbloqueo en el destructor de la clase, que como sabemos será invocado cuando se salga del ámbito de declaración de ésta. Así, cuando nuestra aplicación finalice se desbloquará la WIFI.
En caso de que se intente desbloquear sin haberse bloqueado antes no se generará ninguna excepción, ignorándose la llamada.


Bibliografía:
http://developer.android.com/reference/android/net/wifi/package-summary.html


1 comentario: