API de solicitação de rede Wi-Fi para conectividade ponto a ponto

No Android 10 (nível 29 da API) e em versões mais recentes, é possível usar uma nova API ponto a ponto para iniciar a configuração de dispositivos secundários, como o hardware do Chromecast e do Google Home. Esse recurso permite que seu app solicite ao usuário a alteração do ponto de acesso ao qual o dispositivo está conectado usando WifiNetworkSpecifier para descrever as propriedades de uma rede solicitada.

Para usar essa API, siga as etapas abaixo:

  1. Crie um especificador de rede Wi-Fi usando WifiNetworkSpecifier.Builder.

  2. Defina um filtro de rede para corresponder às redes às quais você pretende se conectar, assim como as credenciais necessárias.

  3. Escolha uma combinação de SSID, SSID pattern, BSSID e BSSID pattern para definir o filtro de rede em cada solicitação, sujeito aos seguintes requisitos:

    • Cada solicitação precisa fornecer pelo menos um entre SSID, SSID pattern, BSSID ou BSSID pattern.
    • Cada solicitação pode definir apenas um entre SSID e SSID pattern.
    • Cada solicitação pode definir apenas um entre BSSID e BSSID pattern.
  4. Adicione os especificadores à solicitação de rede, assim como uma instância NetworkCallback para acompanhar o status da solicitação.

    Se o usuário aceitar a solicitação e houver conexão à rede, NetworkCallback.onAvailable() será invocado no objeto de callback. Se o usuário negar a solicitação ou se a conexão à rede falhar, NetworkCallback.onUnavailable() será invocado no objeto de callback.

A solicitação para se conectar a um dispositivo de mesmo nível exibe uma caixa de diálogo no mesmo dispositivo, na qual o usuário pode aceitar a solicitação de conexão.

Ignorar a aprovação do usuário

Depois que o usuário aprova uma rede para se conectar em resposta a uma solicitação de um app específico, o dispositivo armazena a aprovação para o ponto de acesso. Se o app fizer uma solicitação específica para se conectar a esse ponto de acesso novamente, o dispositivo vai pular a fase de aprovação do usuário e se conectar automaticamente à rede. Se o usuário decidir esquecer a rede enquanto estiver conectado a uma rede solicitada pela API, a aprovação armazenada para essa combinação de app e rede será removida, e qualquer solicitação futura desse app precisará ser aprovada pelo usuário novamente. Se o app fizer uma solicitação não específica, como com um padrão SSID ou BSSID, o usuário precisará aprovar a solicitação.

Exemplo de código

O exemplo de código abaixo mostra como se conectar a uma rede aberta com um prefixo SSID de "test" e um OUI BSSID de "10:03:23":

Kotlin

val specifier = WifiNetworkSpecifier.Builder()
    .setSsidPattern(PatternMatcher("test", PatternMatcher.PATTERN_PREFIX))
    .setBssidPattern(MacAddress.fromString("10:03:23:00:00:00"), MacAddress.fromString("ff:ff:ff:00:00:00"))
    .build()

val request = NetworkRequest.Builder()
    .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
    .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
    .setNetworkSpecifier(specifier)
    .build()

val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

val networkCallback = object : ConnectivityManager.NetworkCallback() {
    ...
    override fun onAvailable(network: Network?) {
        // do success processing here..
    }

    override fun onUnavailable() {
        // do failure processing here..
    }
    ...
}
connectivityManager.requestNetwork(request, networkCallback)
...
// Release the request when done.
connectivityManager.unregisterNetworkCallback(networkCallback)

Java

final NetworkSpecifier specifier =
  new WifiNetworkSpecifier.Builder()
  .setSsidPattern(new PatternMatcher("test", PatternMatcher.PATTERN_PREFIX))
  .setBssidPattern(MacAddress.fromString("10:03:23:00:00:00"), MacAddress.fromString("ff:ff:ff:00:00:00"))
  .build();

final NetworkRequest request =
  new NetworkRequest.Builder()
  .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
  .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
  .setNetworkSpecifier(specifier)
  .build();

final ConnectivityManager connectivityManager = (ConnectivityManager)
  context.getSystemService(Context.CONNECTIVITY_SERVICE);

final NetworkCallback networkCallback = new NetworkCallback() {
  ...
  @Override
  void onAvailable(...) {
      // do success processing here..
  }

  @Override
  void onUnavailable(...) {
      // do failure processing here..
  }
  ...
};
connectivityManager.requestNetwork(request, networkCallback);
...
// Release the request when done.
connectivityManager.unregisterNetworkCallback(networkCallback);