Conexión de tu aplicación a un dispositivo Wi-Fi | Blog para desarrolladores de Android
lunes, 24 de octubre de 2016
Publicado por Rich Hyndman, Developer Advocate de Android
Con la expansión de la Internet de las cosas, la conexión entre aplicaciones de Android y dispositivos compatibles con Wi-Fi es cada vez más común. Si creas una aplicación para un visor remoto, para configurar una lámpara remota conectada o para controlar un cuadricóptero, si se basa en tecnología Wi-Fi, necesitarás conectarte a una zona en la que probablemente no se ofrezca conectividad a Internet.
A partir de Lollipop, el SO comenzó a ser un poco más inteligente, lo que permitió varias conexiones de red y evitó el enrutamiento de datos hacia redes sin conectividad a Internet. Esto resulta muy útil para los usuarios, ya que no pierden la conectividad cuando se encuentran cerca de redes Wi-Fi con portales cautivos. Se agregaron API de enrutamiento de datos para desarrolladores, a fin de que puedas asegurarte de que solo el tráfico de aplicaciones correspondiente se dirija a través de la conexión Wi-Fi hacia el dispositivo externo.
Para facilitar la comprensión de las API, es útil saber que existen 3 conjuntos de redes disponibles para los desarrolladores:
En todas las versiones de Android, puedes comenzar explorando redes Wi-Fi disponibles con WiFiManager#startScan y aplicar iteraciones en ScanResults buscando el SSID de tu dispositivo Wi-Fi externo. Una vez que encuentres una, puedes verificar si ya está configurada medianteWifiManager#getConfiguredNetworks y aplicar iteraciones a través de los objetos WifiConfiguration devueltos estableciendo coincidencias con el SSID. Cabe observar que los SSID de las redes configuradas se encuentran entre comillas dobles, mientras que los SSID devueltos en ScanResults no.
Si tu red está configurada, puedes obtener el ID de red del objeto WifiConfiguration. De lo contrario, puedes configurarla usando WifiManager#addNetwork y realizar un seguimiento del ID de red devuelto.
Para conectarte a la red Wi-Fi, registra un BroadcastReceiver que reciba WifiManager.NETWORK_STATE_CHANGED_ACTION, luego llama a WifiManager.enableNetwork (int netId, booleano disableOthers) y pasa tu ID de red. La llamada enableNetwork deshabilita todos los demás puntos de acceso Wi-Fi para la búsqueda siguiente, localiza el que hayas solicitado y establece una conexión con él. Cuando recibas las difusiones de red, a través de WifiManager#getConnectionInfo podrás verificar que la conexión con la red correspondiente se haya establecido con éxito. Sin embargo, en Lollipop y versiones posteriores, si dicha red no ofrece conectividad con Internet, las solicitudes no se dirigirán hacia ella.
Enrutamiento de solicitudes de red
Para dirigir solicitudes de red de tu aplicación a un dispositivo Wi-Fi externo, en dispositivos con Lollipop llama a ConnectivityManager#setProcessDefaultNetwork y en dispositivos con Marshmallow llama a ConnectivityManager#bindProcessToNetwork, que supone un reemplazo directo de API. Ten en cuenta que para estas llamadas se requiere android.permission.INTERNET; de lo contrario, el resultado devuelto solo será “false”.
Como alternativa, si deseas dirigir parte del tráfico de tu aplicación al dispositivo Wi-Fi y parte a Internet a través de la red móvil:
Ahora puedes mantener conectados a tus usuarios mientras aprovechan los beneficios de tus productos innovadores compatibles con Wi-Fi.
Con la expansión de la Internet de las cosas, la conexión entre aplicaciones de Android y dispositivos compatibles con Wi-Fi es cada vez más común. Si creas una aplicación para un visor remoto, para configurar una lámpara remota conectada o para controlar un cuadricóptero, si se basa en tecnología Wi-Fi, necesitarás conectarte a una zona en la que probablemente no se ofrezca conectividad a Internet.
A partir de Lollipop, el SO comenzó a ser un poco más inteligente, lo que permitió varias conexiones de red y evitó el enrutamiento de datos hacia redes sin conectividad a Internet. Esto resulta muy útil para los usuarios, ya que no pierden la conectividad cuando se encuentran cerca de redes Wi-Fi con portales cautivos. Se agregaron API de enrutamiento de datos para desarrolladores, a fin de que puedas asegurarte de que solo el tráfico de aplicaciones correspondiente se dirija a través de la conexión Wi-Fi hacia el dispositivo externo.
Para facilitar la comprensión de las API, es útil saber que existen 3 conjuntos de redes disponibles para los desarrolladores:
- WiFiManager#startScan devuelve una lista de redes Wi-Fi disponibles. Se identifican principalmente a través de SSID.
- WiFiManager#getConfiguredNetworks devuelve una lista de las redes Wi-Fi configuradas en el dispositivo, también indexadas por SSID, aunque no necesariamente se encuentran disponibles por el momento.
- ConnectivityManager#getAllNetworks devuelve una lista de redes con las cuales interactúa el teléfono. Esto es necesario debido a que, a partir de Lollipop, un dispositivo puede conectarse a varias redes al mismo tiempo (Wi-Fi, LTE, Bluetooth, etc.) Es posible acceder al estado actual de cada una de estas llamando a ConnectivityManager#getNetworkInfo e identificarlo mediante un ID de red.
En todas las versiones de Android, puedes comenzar explorando redes Wi-Fi disponibles con WiFiManager#startScan y aplicar iteraciones en ScanResults buscando el SSID de tu dispositivo Wi-Fi externo. Una vez que encuentres una, puedes verificar si ya está configurada medianteWifiManager#getConfiguredNetworks y aplicar iteraciones a través de los objetos WifiConfiguration devueltos estableciendo coincidencias con el SSID. Cabe observar que los SSID de las redes configuradas se encuentran entre comillas dobles, mientras que los SSID devueltos en ScanResults no.
Si tu red está configurada, puedes obtener el ID de red del objeto WifiConfiguration. De lo contrario, puedes configurarla usando WifiManager#addNetwork y realizar un seguimiento del ID de red devuelto.
Para conectarte a la red Wi-Fi, registra un BroadcastReceiver que reciba WifiManager.NETWORK_STATE_CHANGED_ACTION, luego llama a WifiManager.enableNetwork (int netId, booleano disableOthers) y pasa tu ID de red. La llamada enableNetwork deshabilita todos los demás puntos de acceso Wi-Fi para la búsqueda siguiente, localiza el que hayas solicitado y establece una conexión con él. Cuando recibas las difusiones de red, a través de WifiManager#getConnectionInfo podrás verificar que la conexión con la red correspondiente se haya establecido con éxito. Sin embargo, en Lollipop y versiones posteriores, si dicha red no ofrece conectividad con Internet, las solicitudes no se dirigirán hacia ella.
Enrutamiento de solicitudes de red
Para dirigir solicitudes de red de tu aplicación a un dispositivo Wi-Fi externo, en dispositivos con Lollipop llama a ConnectivityManager#setProcessDefaultNetwork y en dispositivos con Marshmallow llama a ConnectivityManager#bindProcessToNetwork, que supone un reemplazo directo de API. Ten en cuenta que para estas llamadas se requiere android.permission.INTERNET; de lo contrario, el resultado devuelto solo será “false”.
Como alternativa, si deseas dirigir parte del tráfico de tu aplicación al dispositivo Wi-Fi y parte a Internet a través de la red móvil:
- Para solicitudes HTTP, puedes usar Network#openConnection(java.net.URL), y así dirigir de manera directa tu solicitud hacia esta red.
- Para la comunicación de socket de bajo nivel, abre un socket y llama a Network#bindSocket(java.net.Socket) o, como alternativa, usa Network#getSocketFactory.
Ahora puedes mantener conectados a tus usuarios mientras aprovechan los beneficios de tus productos innovadores compatibles con Wi-Fi.