Como faço para conectar-me a uma rede Wi-Fi específica no Android programaticamente?


294

Quero criar um aplicativo que mostre uma lista de redes Wi-Fi disponíveis e conecte-se à rede que for selecionada pelo usuário.

Eu implementei a parte que mostra os resultados da verificação. Agora, quero conectar-me a uma rede específica selecionada pelo usuário na lista de resultados da verificação.

Como eu faço isso?



Isso funcionou para mim WPA2 e WEP: stackoverflow.com/a/29575563/7337517
— Kundan

Respostas:


441

Você precisa criar uma WifiConfigurationinstância como esta:

String networkSSID = "test";
String networkPass = "pass";

WifiConfiguration conf = new WifiConfiguration();
conf.SSID = "\"" + networkSSID + "\"";   // Please note the quotes. String should contain ssid in quotes

Então, para a rede WEP, você precisa fazer o seguinte:

conf.wepKeys[0] = "\"" + networkPass + "\""; 
conf.wepTxKeyIndex = 0;
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40); 

Para rede WPA, você precisa adicionar uma senha como esta:

conf.preSharedKey = "\""+ networkPass +"\"";

Para rede aberta, você precisa fazer o seguinte:

conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);

Em seguida, você precisa adicioná-lo às configurações do gerenciador de wifi do Android:

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

E, finalmente, pode ser necessário ativá-lo, para que o Android se conecte a ele:

List<WifiConfiguration> list = wifiManager.getConfiguredNetworks();
for( WifiConfiguration i : list ) {
    if(i.SSID != null && i.SSID.equals("\"" + networkSSID + "\"")) {
         wifiManager.disconnect();
         wifiManager.enableNetwork(i.networkId, true);
         wifiManager.reconnect();               

         break;
    }           
 }

UPD: No caso de WEP, se sua senha estiver em hexadecimal, não será necessário cercá-la entre aspas.


5
isso funciona bem! obrigado :) mas mais uma coisa que gostaria de perguntar. Você não precisa definir o allowedPairwiseCipher, allowedAuthALgorithms e allowedProtocols? E como decidir qual atributo específico definir; como você configurou o WEP40 para GroupCipher para redes WEP?
— Vikram Gupta

8
Eu esqueci de mencionar uma coisa. No caso de WEP, se sua senha estiver em hexadecimal, você não precisará cercá-la entre aspas.
— Kenota

8
Obrigado pela ótima solução, você pode elaborar como verificar se a conexão foi bem-sucedida ou não. Por exemplo, o usuário pode digitar a senha incorreta e deve ser notificado sobre ela.
— Pascal Klein

3
Que tal se o Hotspot Wifi desejado não usar nenhuma senha ... Devemos usar o .preSharedKey = null; ou devemos definir .preSharedKey = ""; Qual deles está correto? @kenota
— gumuruh

6
Ele não funciona para mim: ele se reconecta diretamente ao wifi lembrado anterior em vez de se conectar ao novo.
— precisa saber é o seguinte

138

A resposta anterior funciona , mas a solução pode realmente ser mais simples. Não é necessário fazer um loop na lista de redes configuradas, pois você obtém o ID da rede ao adicionar a rede através do WifiManager.

Portanto, a solução completa e simplificada ficaria assim:

WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.SSID = String.format("\"%s\"", ssid);
wifiConfig.preSharedKey = String.format("\"%s\"", key);

WifiManager wifiManager = (WifiManager)getSystemService(WIFI_SERVICE);
//remember id
int netId = wifiManager.addNetwork(wifiConfig);
wifiManager.disconnect();
wifiManager.enableNetwork(netId, true);
wifiManager.reconnect();

1
se a senha não for usada. Devemos colocar .preSharedKey = null; ou devemos simplesmente colocar uma string vazia, @seanloyola?
— Gumuruh 19/07

2
@MuhammedRefaat você desconecta caso já esteja conectado a outra rede.
— sean loyola

1
@ gumuruh, você não precisa incluir o objeto presharedkey se não houver uma chave necessária.
— sean loyola

7
de acordo com o javadoc de enableNetwork, se você usar disableOthers boolean verdade, então você não tem que desligar ou ligar, ele vai fazer as duas coisas para você
— NikkyD

12
Provavelmente deve mencionar que a CHANGE_WIFI_STATEpermissão é necessária.
— ThomasW 27/05

27

Antes de conectar a rede WIFI, é necessário verificar o tipo de segurança da classe ScanResult da rede WIFI. Este campo fornece o tipo de rede

Consulte: https://developer.android.com/reference/android/net/wifi/ScanResult.html#capabilities

Existem três tipos de redes Wi-Fi.

Primeiro, instancie um objeto WifiConfiguration e preencha o SSID da rede (observe que ele deve estar entre aspas duplas), defina o estado inicial como desativado e especifique a prioridade da rede (números em torno de 40 parecem funcionar bem).

WifiConfiguration wfc = new WifiConfiguration();

wfc.SSID = "\"".concat(ssid).concat("\"");
wfc.status = WifiConfiguration.Status.DISABLED;
wfc.priority = 40;

Agora, a parte mais complicada: precisamos preencher vários membros do WifiConfiguration para especificar o modo de segurança da rede. Para redes abertas.

wfc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
wfc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
wfc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
wfc.allowedAuthAlgorithms.clear();
wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);

Para redes usando WEP; observe que a chave WEP também está entre aspas duplas.

wfc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
wfc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
wfc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
wfc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
wfc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);

if (isHexString(password)) wfc.wepKeys[0] = password;
else wfc.wepKeys[0] = "\"".concat(password).concat("\"");
wfc.wepTxKeyIndex = 0;

Para redes que usam WPA e WPA2, podemos definir os mesmos valores para ambos.

wfc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
wfc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
wfc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);

wfc.preSharedKey = "\"".concat(password).concat("\"");

Finalmente, podemos adicionar a rede à lista conhecida do WifiManager

WifiManager wfMgr = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
int networkId = wfMgr.addNetwork(wfc);
if (networkId != -1) {
 // success, can call wfMgr.enableNetwork(networkId, true) to connect
} 

uma nota de prioridade, nos meus números de telefone cerca de 4000 funcionaram. provável melhor para fazer essa parte um pouco mais dinâmico (iterate existente configurações etc)
— Sam

Como eu poderia obter o tipo de segurança da rede de SSID para wifi ScanResult
— shantanu

@ Shantanu verifique a seguir para obter detalhes. stackoverflow.com/questions/6866153/…
— Kalpesh Gohel

Nos dispositivos Samsung, a senha é uma string com hash. E o código não funciona. Você confere isso?
— Nguyen Minh Binh

você pode fornecer uma amostra para conectar o EAP do tipo sim wifi?
— Prashanth Debbadwar

19

Crédito para @ raji-ramamoorthi & @kenota

A solução que funcionou para mim é a combinação dos colaboradores acima neste tópico.

Chegar ScanResultaqui é o processo.

WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
if (wifi.isWifiEnabled() == false) {
            Toast.makeText(getApplicationContext(), "wifi is disabled..making it enabled", Toast.LENGTH_LONG).show();
            wifi.setWifiEnabled(true);
        }

BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context c, Intent intent) {
                 wifi.getScanResults();
            }
        };

Aviso aos unregisterlo em onPause& onStopviver estaunregisterReceiver(broadcastReceiver);

public void connectWiFi(ScanResult scanResult) {
        try {

            Log.v("rht", "Item clicked, SSID " + scanResult.SSID + " Security : " + scanResult.capabilities);

            String networkSSID = scanResult.SSID;
            String networkPass = "12345678";

            WifiConfiguration conf = new WifiConfiguration();
            conf.SSID = "\"" + networkSSID + "\"";   // Please note the quotes. String should contain ssid in quotes
            conf.status = WifiConfiguration.Status.ENABLED;
            conf.priority = 40;

            if (scanResult.capabilities.toUpperCase().contains("WEP")) {
                Log.v("rht", "Configuring WEP");    
                conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
                conf.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
                conf.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
                conf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
                conf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
                conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
                conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
                conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
                conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);

                if (networkPass.matches("^[0-9a-fA-F]+$")) {
                    conf.wepKeys[0] = networkPass;
                } else {
                    conf.wepKeys[0] = "\"".concat(networkPass).concat("\"");
                }

                conf.wepTxKeyIndex = 0;

            } else if (scanResult.capabilities.toUpperCase().contains("WPA")) {
                Log.v("rht", "Configuring WPA");

                conf.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
                conf.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
                conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
                conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
                conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
                conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
                conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
                conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
                conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);

                conf.preSharedKey = "\"" + networkPass + "\"";

            } else {
                Log.v("rht", "Configuring OPEN network");
                conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
                conf.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
                conf.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
                conf.allowedAuthAlgorithms.clear();
                conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
                conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
                conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
                conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
                conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
                conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            }

            WifiManager wifiManager = (WifiManager) WiFiApplicationCore.getAppContext().getSystemService(Context.WIFI_SERVICE);
            int networkId = wifiManager.addNetwork(conf);

            Log.v("rht", "Add result " + networkId);

            List<WifiConfiguration> list = wifiManager.getConfiguredNetworks();
            for (WifiConfiguration i : list) {
                if (i.SSID != null && i.SSID.equals("\"" + networkSSID + "\"")) {
                    Log.v("rht", "WifiConfiguration SSID " + i.SSID);

                    boolean isDisconnected = wifiManager.disconnect();
                    Log.v("rht", "isDisconnected : " + isDisconnected);

                    boolean isEnabled = wifiManager.enableNetwork(i.networkId, true);
                    Log.v("rht", "isEnabled : " + isEnabled);

                    boolean isReconnected = wifiManager.reconnect();
                    Log.v("rht", "isReconnected : " + isReconnected);

                    break;
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

5

Se o seu dispositivo conhece as configurações Wifi (já armazenadas), podemos ignorar a ciência dos foguetes. Basta percorrer as configurações e verificar se o SSID está correspondendo. Nesse caso, conecte e retorne .

Defina permissões:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />

Conectar:

    try {
    String ssid = null;
    if (wifi == Wifi.PCAN_WIRELESS_GATEWAY) {
        ssid = AesPrefs.get(AesConst.PCAN_WIRELESS_SSID,
                context.getString(R.string.pcan_wireless_ssid_default));
    } else if (wifi == Wifi.KJ_WIFI) {
        ssid = context.getString(R.string.remote_wifi_ssid_default);
    }

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

    List<WifiConfiguration> wifiConfigurations = wifiManager.getConfiguredNetworks();

    for (WifiConfiguration wifiConfiguration : wifiConfigurations) {
        if (wifiConfiguration.SSID.equals("\"" + ssid + "\"")) {
            wifiManager.enableNetwork(wifiConfiguration.networkId, true);
            Log.i(TAG, "connectToWifi: will enable " + wifiConfiguration.SSID);
            wifiManager.reconnect();
            return null; // return! (sometimes logcat showed me network-entries twice,
            // which may will end in bugs)
        }
    }
} catch (NullPointerException | IllegalStateException e) {
    Log.e(TAG, "connectToWifi: Missing network configuration.");
}
return null;

5

Quebrei a cabeça para entender por que suas respostas para o WPA / WPA2 não funcionam ... depois de horas de tentativas, encontrei o que está faltando:

conf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);

É NECESSÁRIO para redes WPA !!!!

Agora, funciona :)


4

Esta é uma atividade que você pode subclassificar para forçar a conexão a um wifi específico: https://github.com/zoltanersek/android-wifi-activity/blob/master/app/src/main/java/com/zoltanersek/androidwifiactivity/ WifiActivity.java

Você precisará subclassificar esta atividade e implementar seus métodos:

public class SampleActivity extends WifiBaseActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
  }

  @Override
  protected int getSecondsTimeout() {
      return 10;
  }

  @Override
  protected String getWifiSSID() {
      return "WifiNetwork";
  }

  @Override
  protected String getWifiPass() {
      return "123456";
  }
}

link down você pode dar o novo?
— fácil

4

No nível 29 da API, o WifiManager.enableNetwork()método está obsoleto . De acordo com a documentação da API do Android (confira aqui ):

  1. Consulte WifiNetworkSpecifier.Builder # build () para obter um novo mecanismo para acionar a conexão a uma rede Wi-Fi.
  2. Consulte addNetworkSuggestions (java.util.List), removeNetworkSuggestions (java.util.List) para obter uma nova API para adicionar redes Wi-Fi para consideração ao se conectar automaticamente ao wifi. Nota de compatibilidade: Para aplicativos direcionados ao Build.VERSION_CODES.Q ou superior, essa API sempre retornará false.

No nível 29 da API, para conectar-se à rede Wi-Fi, você precisará usar WifiNetworkSpecifier. Você pode encontrar um exemplo de código em https://developer.android.com/reference/android/net/wifi/WifiNetworkSpecifier.Builder.html#build ()


É possível conectar-se a uma rede WEP com o novo WifiNetWorkSpecifier.Builder? Não consigo encontrar um método para adicionar uma senha WEP ao construtor.
— Dieter27

O número 1 parece não funcionar. Existe algum retorno de chamada?
— Faizan Mir

1

Eu também tentei me conectar à rede. Nenhuma das soluções propostas acima funciona para o hugerock t70. Função wifiManager.disconnect (); não desconecta da rede atual. Portanto, não é possível reconectar-se à rede especificada. Eu modifiquei o código acima. Para mim, o código bolow funciona perfeitamente:

String networkSSID = "test";
String networkPass = "pass";

WifiConfiguration conf = new WifiConfiguration();
conf.SSID = "\"" + networkSSID + "\"";   
conf.wepKeys[0] = "\"" + networkPass + "\""; 
conf.wepTxKeyIndex = 0;
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40); 
conf.preSharedKey = "\""+ networkPass +"\"";

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

int networkId = wifiManager.addNetwork(conf);
wifi_inf = wifiManager.getConnectionInfo();

/////important!!!
wifiManager.disableNetwork(wifi_inf.getNetworkId());
/////////////////

wifiManager.enableNetwork(networkId, true);

Recebo um erro no Android 10:UID nnnnn does not have permission to update configuration xxxx. MD_START_CONNECT but no requests and connected, but app does not have sufficient permissions, bailing.
— Luis A. Florit

0

Tente este método. É muito fácil:

public static boolean setSsidAndPassword(Context context, String ssid, String ssidPassword) {
    try {
        WifiManager wifiManager = (WifiManager) context.getSystemService(context.WIFI_SERVICE);
        Method getConfigMethod = wifiManager.getClass().getMethod("getWifiApConfiguration");
        WifiConfiguration wifiConfig = (WifiConfiguration) getConfigMethod.invoke(wifiManager);

        wifiConfig.SSID = ssid;
        wifiConfig.preSharedKey = ssidPassword;

        Method setConfigMethod = wifiManager.getClass().getMethod("setWifiApConfiguration", WifiConfiguration.class);
        setConfigMethod.invoke(wifiManager, wifiConfig);

        return true;
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.