Los dispositivos que ejecutan Android 10 (nivel de API 29) y versiones posteriores permiten que tu app agregue credenciales de red para que un dispositivo se conecte automáticamente a un punto de acceso Wi-Fi. Puedes usar WifiNetworkSuggestion
para brindar sugerencias de redes a las cuales conectarse.
En última instancia, la plataforma elige qué punto de acceso aceptar en función de la entrada de tu app y de otras.
En Android 11 (nivel de API 30) y versiones posteriores, haz lo siguiente:
- La API de sugerencias admite el aprovisionamiento de un
PasspointConfiguration
. Antes de Android 11, aprovisionar unPasspointConfiguration
requiere el uso de la API deaddOrUpdatePasspointConfiguration()
. - El framework aplica de manera forzosa los requisitos de seguridad de las sugerencias empresariales basadas en TLS (EAP-TLS, EAP-TTLS y EAP-PEAP); las sugerencias para esas redes deben establecer un
Root CA certificate
y unserver domain name
.
- El framework aplica requisitos de propiedad para las sugerencias empresariales basadas en EAP-SIM (EAP-SIM, EAP-AKA y EAP-AKA-PRIME). Solo las apps firmadas por el operador permiten esas sugerencias.
- En el caso de las sugerencias que proporciona una app firmada por un operador, el framework les asigna automáticamente un ID de operador correspondiente a la firma del operador de la app. Estas sugerencias se inhabilitan automáticamente si se quita la SIM correspondiente del dispositivo.
En Android 12 (nivel de API 31) y versiones posteriores:
Se puede habilitar privacidad adicional mediante la aleatorización de MAC no persistente, que vuelve a aleatorizar periódicamente la dirección MAC aleatoria. Usa
setMacRandomizationSetting
para especificar el nivel de aleatorización de tu red.isPasspointTermsAndConditionsSupported()
:Términos y condiciones es una función de Passpoint que permite que las implementaciones de redes reemplacen portales cautivos no seguros, que usan redes abiertas, por una red segura de Passpoint. Se le muestra una notificación al usuario cuando debe aceptar términos y condiciones. Las apps que sugieren redes de Passpoint que están restringidas por términos y condiciones deben llamar primero a esta API para asegurarse de que el dispositivo admita la función. Si el dispositivo no la admite, no podrá conectarse a esta red, y se sugerirá una red alternativa o heredada.isDecoratedIdentitySupported()
: Cuando te autenticas en redes extendidas con un prefijo, el prefijo con identidad extendido permite que los operadores de red actualicen el identificador de acceso a la red (NAI) para realizar el enrutamiento explícito a través de varios proxies dentro de una red AAA (consulta RFC 7542 para obtener más información al respecto).Android 12 implementa esta función a fin de cumplir con la especificación de WBA para extensiones PPS-MO. Las apps que sugieren redes de Passpoint que requieren una identidad extendida deben llamar primero a esta API para asegurarse de que el dispositivo admita la función. Si el dispositivo no la admite, la identidad no se extenderá, y es posible que falle la autenticación en la red.
Para crear una sugerencia de Passpoint, las apps deben usar las clases PasspointConfiguration
, Credential
y HomeSp
. Estas clases describen el perfil de Passpoint, que se define en la especificación de Passpoint de Wi-Fi Alliance.
En la siguiente muestra de código, se muestra cómo proporcionar credenciales para una red abierta, una WPA2, una WPA3 y una red Passpoint:
Kotlin
val suggestion1 = WifiNetworkSuggestion.Builder() .setSsid("test111111") .setIsAppInteractionRequired(true) // Optional (Needs location permission) .build(); val suggestion2 = WifiNetworkSuggestion.Builder() .setSsid("test222222") .setWpa2Passphrase("test123456") .setIsAppInteractionRequired(true) // Optional (Needs location permission) .build(); val suggestion3 = WifiNetworkSuggestion.Builder() .setSsid("test333333") .setWpa3Passphrase("test6789") .setIsAppInteractionRequired(true) // Optional (Needs location permission) .build(); val passpointConfig = PasspointConfiguration(); // configure passpointConfig to include a valid Passpoint configuration val suggestion4 = WifiNetworkSuggestion.Builder() .setPasspointConfig(passpointConfig) .setIsAppInteractionRequired(true) // Optional (Needs location permission) .build(); val suggestionsList = listOf(suggestion1, suggestion2, suggestion3, suggestion4); val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager; val status = wifiManager.addNetworkSuggestions(suggestionsList); if (status != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) { // do error handling here } // Optional (Wait for post connection broadcast to one of your suggestions) val intentFilter = IntentFilter(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION); val broadcastReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { if (!intent.action.equals(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION)) { return; } // do post connect processing here } }; context.registerReceiver(broadcastReceiver, intentFilter);
Java
final WifiNetworkSuggestion suggestion1 = new WifiNetworkSuggestion.Builder() .setSsid("test111111") .setIsAppInteractionRequired(true) // Optional (Needs location permission) .build(); final WifiNetworkSuggestion suggestion2 = new WifiNetworkSuggestion.Builder() .setSsid("test222222") .setWpa2Passphrase("test123456") .setIsAppInteractionRequired(true) // Optional (Needs location permission) .build(); final WifiNetworkSuggestion suggestion3 = new WifiNetworkSuggestion.Builder() .setSsid("test333333") .setWpa3Passphrase("test6789") .setIsAppInteractionRequired(true) // Optional (Needs location permission) .build(); final PasspointConfiguration passpointConfig = new PasspointConfiguration(); // configure passpointConfig to include a valid Passpoint configuration final WifiNetworkSuggestion suggestion4 = new WifiNetworkSuggestion.Builder() .setPasspointConfig(passpointConfig) .setIsAppInteractionRequired(true) // Optional (Needs location permission) .build(); final List<WifiNetworkSuggestion> suggestionsList = new ArrayList<WifiNetworkSuggestion> {{ add(suggestion1); add(suggestion2); add(suggestion3); add(suggestion4); }}; final WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); final int status = wifiManager.addNetworkSuggestions(suggestionsList); if (status != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) { // do error handling here… } // Optional (Wait for post connection broadcast to one of your suggestions) final IntentFilter intentFilter = new IntentFilter(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION); final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (!intent.getAction().equals( WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION)) { return; } // do post connect processing here... } }; context.registerReceiver(broadcastReceiver, intentFilter);
Se notifica al usuario inmediatamente después de que la app realiza una sugerencia por primera vez. El tipo de notificación depende de la versión de Android que se ejecute en el dispositivo:
- En Android 11 (nivel de API 30) y versiones posteriores, el usuario ve un diálogo si la app se ejecuta en primer plano y una notificación si se ejecuta en segundo plano.
- En Android 10 (nivel de API 29), el usuario ve una notificación, independientemente de si la app se ejecuta en primer o segundo plano.
Cuando la plataforma se conecta a una de las sugerencias de red, la configuración muestra un texto que atribuye la conexión de red a la app que realizó la sugerencia correspondiente.
Cómo administrar desconexiones del usuario
Si el usuario utiliza el selector de Wi-Fi para desconectarse explícitamente de una de las sugerencias de red cuando está conectado a ella, esa red se ignora cuando aún está dentro del alcance. Durante este período, no se considerará esa red para la conexión automática, incluso si la app quita y vuelve a agregar la sugerencia de red correspondiente. Si el usuario usa el selector de Wi-Fi para conectarse de forma explícita a una red que se desconectó anteriormente, esa red se considerará para la conexión automática de inmediato.
Cómo cambiar el estado de autorización para una app
Un usuario que rechaza la notificación de la sugerencia de red quita el permiso CHANGE_WIFI_STATE
de la app. El usuario puede otorgar esta aprobación más adelante desde el menú de control de Wi-Fi (Configuración > Apps y notificaciones > Acceso especial a apps > Control de Wi-Fi > App name).