Em dispositivos com Android 10 (API de nível 29) e versões mais recentes, seu app pode adicionar credenciais de rede para que um dispositivo se conecte automaticamente a um ponto de acesso Wi-Fi. Você pode fornecer sugestões de redes para a conexão usando WifiNetworkSuggestion.
A plataforma escolhe qual ponto de acesso será aceito com base na entrada do seu app e de outros.
No Android 11 (API de nível 30) e versões mais recentes:
- O provisionamento de um PasspointConfigurationé compatível com a API de sugestões. Antes do Android 11, o provisionamento de umPasspointConfigurationexigia o uso da APIaddOrUpdatePasspointConfiguration().
- O framework aplica requisitos de segurança em sugestões empresariais baseadas em TLS (EAP-TLS, EAP-TTLS e EAP-PEAP). As sugestões para essas redes precisam definir um Root CA certificatee umserver domain name.
- O framework impõe requisitos de propriedade para sugestões empresariais baseadas em EAP-SIM (EAP-SIM, EAP-AKA, EAP-AKA-PRIME). Essas sugestões são permitidas apenas por apps assinados pela operadora.
- Para sugestões fornecidas por um app assinado por uma operadora, o framework atribui automaticamente um ID de operadora correspondente à assinatura da operadora do app. Essas sugestões são desativadas automaticamente se o chip correspondente for removido do dispositivo.
No Android 12 (nível 31 da API) e em versões mais recentes:
- É possível ativar mais privacidade com a aleatorização não persistente de MAC, que aleatoriza periodicamente o endereço MAC aleatório. Use - setMacRandomizationSettingpara especificar o nível de randomização da sua rede.
- isPasspointTermsAndConditionsSupported(): os Termos e Condições são um recurso do Passpoint que possibilita que as implantações de rede substituam o portal cativo não seguro, que usa redes abertas, por uma rede do Passpoint segura. O usuário recebe uma notificação quando ele for solicitado a aceitar os Termos e Condições. Os apps que sugerem redes de Passpoint controladas por Termos e Condições, precisam chamar essa API primeiro para ter certeza de que o dispositivo é compatível com a funcionalidade. Se o dispositivo não for compatível com o recurso, ele não poderá se conectar a essa rede, e será necessário sugerir uma rede alternativa ou legada.
- isDecoratedIdentitySupported(): ao autenticar em redes com uma decoração prefixada, o prefixo de identidade decorado possibilita que os operadores de rede atualizem o identificador de acesso à rede (NAI, na sigla em inglês) para executar o roteamento explícito usando vários proxies dentro de uma rede AAA. Consulte RFC 7542 (link em inglês) para saber mais sobre isso.- O Android 12 implementa esse recurso para estar em conformidade com as especificações da WBA para extensões PPS-MO (link em inglês). Os apps que sugerem redes do Passpoint que exigem uma identidade decorada, precisam chamar essa API primeiro para garantir que dispositivo é compatível com a funcionalidade. Se o dispositivo não for compatível com o recurso, a identidade não será decorada e a autenticação na rede pode falhar. 
Para criar uma sugestão de Passpoint, os apps precisam usar as classes
PasspointConfiguration,
Credential
e HomeSp. Essas
classes descrevem o perfil do Passpoint, definido na especificação do Passpoint
do Wi-Fi
Alliance (em inglês).
A amostra de código a seguir mostra como fornecer credenciais para uma rede aberta, uma rede WPA2, uma rede WPA3 e uma rede 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);
Imediatamente após o app fazer uma sugestão pela primeira vez, o usuário recebe uma notificação. O tipo de notificação depende da versão do Android em execução no dispositivo:
- No Android 11 (nível 30 da API) e versões mais recentes, o usuário vê uma caixa de diálogo se o app estiver em execução em primeiro plano e uma notificação se o app estiver em execução em segundo plano.
- No Android 10 (nível 29 da API), o usuário vê uma notificação, independente de o app estar em primeiro ou segundo plano.
Quando a plataforma se conecta a uma das sugestões de rede, as configurações mostram um texto que atribui a conexão de rede ao app que fez a sugestão.
Processamento de desconexões do usuário
Se o usuário usar o seletor de Wi-Fi para se desconectar explicitamente de uma das sugestões da rede quando estiver conectado a ela, essa rede será ignorada enquanto ainda estiver no alcance. Durante esse período, a rede em questão não será considerada para conexão automática, mesmo se o app remover e adicionar novamente a sugestão dessa rede. Se o usuário usar o seletor de Wi-Fi para se conectar explicitamente a uma rede que foi desconectada anteriormente, essa rede será considerada para conexão automática imediatamente.
Alteração do status de aprovação para o aplicativo
Quando um usuário recusa a notificação de sugestão de rede, a permissão CHANGE_WIFI_STATE é removida do app. O usuário pode conceder essa aprovação posteriormente acessando o menu de controle de Wi-Fi (Config. > Apps e notificações > Acesso especial a apps > Controle de Wi-Fi > App name).
