Visão geral da verificação de Wi-Fi

Use os recursos de verificação de Wi-Fi fornecidos pela API WifiManager para receber uma lista de pontos de acesso Wi-Fi visíveis no dispositivo.

Processo de busca por Wi-Fi

Há três etapas para o processo de busca:

  1. Registre um listener de transmissão para SCAN_RESULTS_AVAILABLE_ACTION, que é enviado quando as solicitações de verificação são concluídas, fornecendo o status de sucesso ou falha. Para dispositivos que executam o Android 10 (API de nível 29) e versões mais recentes, essa transmissão será enviada para qualquer busca por Wi-Fi completa realizada no dispositivo, seja pela plataforma ou por outros aplicativos. Com a transmissão, os aplicativos podem interceptar passivamente todas as conclusões da busca no dispositivo sem emitir uma busca própria.

  2. Solicite uma verificação usando WifiManager.startScan(). Verifique o status de retorno do método, porque a chamada pode falhar por qualquer um dos seguintes motivos:

    • As solicitações de verificação podem ser limitadas devido a muitas verificações em um curto período.
    • O dispositivo está ocioso, e a busca está desativada.
    • O hardware Wi-Fi relata uma falha na busca.
  3. Receba os resultados da verificação usando WifiManager.getScanResults(). Os resultados retornados são os mais recentes, que podem ser de uma verificação anterior se a atual não tiver sido concluída ou bem-sucedida. Isso significa que você pode receber resultados de verificação mais antigos se chamar esse método antes de receber uma transmissão SCAN_RESULTS_AVAILABLE_ACTION bem-sucedida.

O código a seguir fornece um exemplo de como implementar essas etapas:

Kotlin

val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager

val wifiScanReceiver = object : BroadcastReceiver() {

  override fun onReceive(context: Context, intent: Intent) {
    val success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)
    if (success) {
      scanSuccess()
    } else {
      scanFailure()
    }
  }
}

val intentFilter = IntentFilter()
intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)
context.registerReceiver(wifiScanReceiver, intentFilter)

val success = wifiManager.startScan()
if (!success) {
  // scan failure handling
  scanFailure()
}

....

private fun scanSuccess() {
  val results = wifiManager.scanResults
  ... use new scan results ...
}

private fun scanFailure() {
  // handle failure: new scan did NOT succeed
  // consider using old scan results: these are the OLD results!
  val results = wifiManager.scanResults
  ... potentially use older scan results ...
}

Java

WifiManager wifiManager = (WifiManager)
                   context.getSystemService(Context.WIFI_SERVICE);

BroadcastReceiver wifiScanReceiver = new BroadcastReceiver() {
  @Override
  public void onReceive(Context c, Intent intent) {
    boolean success = intent.getBooleanExtra(
                       WifiManager.EXTRA_RESULTS_UPDATED, false);
    if (success) {
      scanSuccess();
    } else {
      // scan failure handling
      scanFailure();
    }
  }
};

IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
context.registerReceiver(wifiScanReceiver, intentFilter);

boolean success = wifiManager.startScan();
if (!success) {
  // scan failure handling
  scanFailure();
}

....

private void scanSuccess() {
  List<ScanResult> results = wifiManager.getScanResults();
  ... use new scan results ...
}

private void scanFailure() {
  // handle failure: new scan did NOT succeed
  // consider using old scan results: these are the OLD results!
  List<ScanResult> results = wifiManager.getScanResults();
  ... potentially use older scan results ...
}

Restrições

O Android 8.0 (nível 26 da API) introduziu restrições sobre permissões e a frequência de buscas por Wi-Fi permitida.

Para melhorar o desempenho da rede, a segurança e a duração da bateria, o Android 9 (nível 28 da API) reforçou os requisitos de permissão e limitou ainda mais a frequência das buscas por Wi-Fi.

Permissões

Android 8.0 (nível 26 da API) e Android 8.1 (nível 27 da API):

Uma chamada bem-sucedida para WifiManager.getScanResults() requer qualquer uma das seguintes permissões:

Se o app não tiver nenhuma dessas permissões, a chamada falhará com um SecurityException.

Como alternativa, em dispositivos com o Android 8.0 (nível 26 da API) e versões mais recentes, é possível usar o CompanionDeviceManager para realizar uma verificação de dispositivos complementares por perto em nome do app sem exigir a permissão de localização. Para mais informações sobre essa opção, consulte Pareamento de dispositivos complementares.

Android 9 (nível 28 da API):

Uma chamada bem-sucedida para WifiManager.startScan() exige que todas as seguintes condições sejam atendidas:

  • O app tem a permissão ACCESS_FINE_LOCATION ou ACCESS_COARSE_LOCATION.
  • O app tem a permissão CHANGE_WIFI_STATE.
  • Os serviços de localização estão ativados no dispositivo, em Configurações → Local.

Android 10 (nível 29 da API) e versões mais recentes:

Uma chamada bem-sucedida para WifiManager.startScan() exige que todas as seguintes condições sejam atendidas:

  • Se o aplicativo for destinado ao SDK do Android 10 (API de nível 29) ou mais recente, ele terá a permissão ACCESS_FINE_LOCATION.
  • Se o aplicativo for destinado a um SDK anterior ao Android 10 (API de nível 29), ele terá a permissão ACCESS_COARSE_LOCATION ou ACCESS_FINE_LOCATION.
  • O app tem a permissão CHANGE_WIFI_STATE.
  • Os serviços de localização estão ativados no dispositivo em Configurações > Local.

Para chamar WifiManager.getScanResults(), verifique se todas as condições a seguir foram atendidas:

  • Se o aplicativo for destinado ao SDK do Android 10 (API de nível 29) ou mais recente, ele terá a permissão ACCESS_FINE_LOCATION.
  • Se o aplicativo for destinado a um SDK anterior ao Android 10 (API de nível 29), ele terá a permissão ACCESS_COARSE_LOCATION ou ACCESS_FINE_LOCATION.
  • O app tem a permissão ACCESS_WIFI_STATE.
  • Os serviços de localização estão ativados no dispositivo em Configurações > Local.

Se o app de ligação não atender a todos esses requisitos, a ligação vai falhar com um SecurityException.

Limitação

As seguintes limitações se aplicam à frequência de buscas que usam WifiManager.startScan().

Android 8.0 e Android 8.1:

Os aplicativos em segundo plano podem fazer uma busca a cada 30 minutos.

Android 9:

Os aplicativos em primeiro plano podem fazer quatro buscas a cada 2 minutos. Isso permite a ocorrência de um burst de buscas em pouco tempo.

Todos os aplicativos em segundo plano combinados podem fazer uma busca a cada 30 minutos.

Android 10 e versões mais recentes:

São aplicadas as mesmas limitações do Android 9. Há uma nova opção do desenvolvedor para desativar a limitação para testes locais (em Opções do desenvolvedor > Rede > Limitação de busca de Wi-Fi).