Dispositivos com Android 10 (nível 29 da API) e mais recentes permitem que o app adicione credenciais
de rede para que um dispositivo se conecte automaticamente a um ponto de acesso Wi-Fi. Você pode sugerir
a que rede se conectar usando
WifiNetworkSuggestion
.
A plataforma escolhe qual ponto de acesso aceitar 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 um
PasspointConfiguration
é aceito pela API de sugestões. Antes do Android 11, provisionar umPasspointConfiguration
requer o uso da APIaddOrUpdatePasspointConfiguration()
. - O framework aplica os 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 certificate
e umserver domain name
.
- O framework aplica os 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 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 cartã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 re-randomiza periodicamente o endereço MAC aleatório. Use
setMacRandomizationSetting
para especificar o nível de randomização da 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).
O exemplo de código a seguir mostra como fornecer credenciais para uma rede aberta, uma WPA2, uma 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 colocar uma sugestão pela primeira vez, o usuário é notificado. O tipo de notificação depende da versão do Android usada no dispositivo:
- No Android 11 (nível 30 da API) e versões mais recentes, o usuário recebe uma caixa de diálogo se o app estiver em execução 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 o texto que atribui a conexão de rede ao app correspondente 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 de rede quando estiver conectado a ela, essa rede será ignorada quando ainda estiver no intervalo. Durante esse período, a rede não será considerada para conexão automática, mesmo que o app remova e adicione novamente a sugestão correspondente à rede. Se o usuário usar o seletor de Wi-Fi para se conectar explicitamente a uma rede que estava desconectada, 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
mais tarde acessando o menu de controle de Wi-Fi (Configurações >
Apps e notificações > Acesso especial a
apps > Controle de Wi-Fi > App name).