Dispositivos com o Android 10 (nível 29 da API) e versões mais recentes permitem que seu app adicione credenciais de rede para que um dispositivo seja conectado automaticamente a um ponto de acesso Wi-Fi. Você pode fornecer
sugestões de qual rede se conectar usando
WifiNetworkSuggestion.
A plataforma escolhe qual ponto de acesso será aceito com base na entrada do seu app e de outros.
No Android 11 (nível 30 da API) e versões mais recentes:
- O provisionamento de uma
PasspointConfigurationé compatível com a API de sugestão. Antes do Android 11, o provisionamento de umPasspointConfigurationexige o uso da APIaddOrUpdatePasspointConfiguration(). - O framework aplica requisitos de segurança em sugestões corporativas 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 aplica requisitos de propriedade para sugestões corporativas 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 pela operadora, o framework atribui automaticamente um ID de operadora correspondente à assinatura da operadora do app . Essas sugestões são desativadas automaticamente se o SIM correspondente for removido do dispositivo.
No Android 12 (nível 31 da API) e versões mais recentes:
É possível ativar mais privacidade usando a randomização de MAC não persistente, que randomiza novamente o endereço MAC aleatório periodicamente. Use
setMacRandomizationSettingpara especificar o nível de randomização da sua rede.isPasspointTermsAndConditionsSupported(): Termos e Condições é 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.
O exemplo de código a seguir mostra como fornecer credenciais para uma rede aberta, uma rede WPA2, uma rede WPA3 e uma rede do 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 é notificado. 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 primeiro plano e uma notificação se o app estiver em segundo plano.
- No Android 10 (nível 29 da API), o usuário recebe uma notificação, independentemente 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.
Lidar com 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 quando 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.
Alterar o status de aprovação para o app
Um usuário que recusar a notificação de sugestão de rede remove a
CHANGE_WIFI_STATE permissão do app. O usuário pode conceder essa aprovação
posteriormente acessando o menu de controle de Wi-Fi (Configurações >
Apps e notificações > Acesso especial a
apps > Controle de Wi-Fi > App name).