Comment puis-je me connecter à un réseau Wi-Fi spécifique dans Android par programme?

294

Je souhaite concevoir une application qui affiche une liste des réseaux Wi-Fi disponibles et me connecter au réseau sélectionné par l'utilisateur.

J'ai implémenté la partie montrant les résultats de l'analyse. Maintenant, je veux me connecter à un réseau particulier sélectionné par l'utilisateur dans la liste des résultats de l'analyse.

Comment puis-je faire cela?

Vikram Gupta
la source

Réponses:

441

Vous devez créer une WifiConfigurationinstance comme celle-ci:

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

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

Ensuite, pour le réseau WEP, vous devez procéder comme suit:

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

Pour le réseau WPA, vous devez ajouter une phrase secrète comme ceci:

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

Pour le réseau ouvert, vous devez faire ceci:

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

Ensuite, vous devez l'ajouter aux paramètres du gestionnaire wifi Android:

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

Et enfin, vous devrez peut-être l'activer, afin que Android s'y connecte:

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: En cas de WEP, si votre mot de passe est en hexadécimal, vous n'avez pas besoin de l'entourer de guillemets.

kenota
la source
5
ça marche bien! merci :) mais encore une chose que je voudrais demander. N'avez-vous pas besoin de définir les paramètres allowedPairwiseCipher, allowedAuthALgorithms et allowedProtocols? Et comment décider quel attribut particulier définir; comme vous définissez WEP40 pour GroupCipher pour les réseaux WEP?
Vikram Gupta
8
J'ai oublié de mentionner une chose. En cas de WEP, si votre mot de passe est en hexadécimal, vous n'avez pas besoin de l'entourer de guillemets.
kenota
8
Merci pour la bonne solution, pourriez-vous nous expliquer comment vérifier si la connexion a réussi ou non. Par exemple, l'utilisateur peut entrer un mot de passe incorrect et doit en être informé.
Pascal Klein
3
que diriez-vous si le Hotspot Wifi souhaité n'utilise aucun mot de passe ... Devrions-nous utiliser le .preSharedKey = null; ou devrions-nous définir .preSharedKey = ""; Laquelle est correcte? @kenota
gumuruh
6
Cela ne fonctionne pas pour moi: il se reconnecte directement au wifi mémorisé précédent au lieu de se connecter au nouveau.
Virthuss
138

La réponse précédente fonctionne , mais la solution peut en fait être plus simple. Il n'est pas nécessaire de parcourir la liste des réseaux configurés car vous obtenez l'ID réseau lorsque vous ajoutez le réseau via le WifiManager.

Ainsi, la solution complète et simplifiée ressemblerait à ceci:

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();
sean loyola
la source
1
si le mot de passe n'est pas utilisé. Faut-il mettre .preSharedKey = null; ou devrions-nous simplement mettre une chaîne vide, @seanloyola?
gumuruh
2
@MuhammedRefaat vous vous déconnectez au cas où vous êtes déjà connecté à un autre réseau.
sean loyola
1
@gumuruh vous n'avez pas du tout à inclure l'objet presharedkey s'il n'y a pas de clé requise.
sean loyola
7
selon le javadoc de enableNetwork, si vous utilisez boolean disableOthers true, alors vous n'avez pas besoin de vous déconnecter ou de vous connecter, cela fera les deux pour vous
NikkyD
12
Devrait probablement mentionner que l' CHANGE_WIFI_STATEautorisation est nécessaire.
ThomasW
27

Avant de vous connecter au réseau WIFI, vous devez vérifier le type de sécurité du réseau WIFI La classe ScanResult a des capacités. Ce champ vous donne le type de réseau

Référez-vous à: https://developer.android.com/reference/android/net/wifi/ScanResult.html#capabilities

Il existe trois types de réseaux WIFI.

Tout d'abord, instanciez un objet WifiConfiguration et remplissez le SSID du réseau (notez qu'il doit être mis entre guillemets), définissez l'état initial sur désactivé et spécifiez la priorité du réseau (les nombres autour de 40 semblent bien fonctionner).

WifiConfiguration wfc = new WifiConfiguration();

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

Maintenant, pour la partie la plus compliquée: nous devons remplir plusieurs membres de WifiConfiguration pour spécifier le mode de sécurité du réseau. Pour les réseaux ouverts.

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);

Pour les réseaux utilisant WEP; notez que la clé WEP est également placée entre guillemets.

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;

Pour les réseaux utilisant WPA et WPA2, nous pouvons définir les mêmes valeurs pour les deux.

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("\"");

Enfin, nous pouvons ajouter le réseau à la liste connue du 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
} 
raji ramamoorthi
la source
une note sur la priorité, sur mes numéros de téléphone environ 4000 ont fonctionné. mieux vaut probablement rendre cette partie un peu plus dynamique (itérer les configurations existantes, etc.)
Sam
Comment puis-je obtenir le type de sécurité réseau du SSID pour wifi ScanResult
shantanu
@shantanu vérifiez les détails ci-dessous. stackoverflow.com/questions/6866153/…
Kalpesh Gohel
Sur les appareils Samsung, la phrase secrète est une chaîne hachée. Et le code ne fonctionne pas. Vérifiez-vous cela?
Nguyen Minh Binh
pouvez-vous fournir un échantillon pour connecter EAP de type sim wifi?
Prashanth Debbadwar
19

Crédit à @ raji-ramamoorthi & @kenota

La solution qui a fonctionné pour moi est la combinaison des contributeurs ci-dessus dans ce fil.

Pour arriver ScanResultici, c'est le processus.

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();
            }
        };

Avisez unregister-le onPauseet onStopvivez celaunregisterReceiver(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();
        }
    }
Rohit Mandiwal
la source
5

Si votre appareil connaît les configurations Wifi (déjà stockées), nous pouvons contourner la science des fusées. Il suffit de parcourir les configurations pour vérifier si le SSID correspond. Si oui, connectez-vous et revenez .

Définissez les autorisations:

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

Relier:

    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;
Martin Pfeffer
la source
5

Je me suis cassé la tête pour comprendre pourquoi vos réponses pour WPA / WPA2 ne fonctionnent pas ... après des heures d'essais, j'ai trouvé ce qui vous manquait:

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

est REQUIS pour les réseaux WPA !!!!

Maintenant ça marche :)

Taras Okunev
la source
4

Il s'agit d'une activité que vous pouvez sous-classer pour forcer la connexion à un wifi spécifique: https://github.com/zoltanersek/android-wifi-activity/blob/master/app/src/main/java/com/zoltanersek/androidwifiactivity/ WifiActivity.java

Vous devrez sous-classer cette activité et implémenter ses méthodes:

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";
  }
}
Zoltan Ersek
la source
lien vers le bas pouvez-vous donner le nouveau?
StartCoding
4

Dans l'API niveau 29, la WifiManager.enableNetwork()méthode est obsolète . Selon la documentation de l'API Android (vérifiez ici ):

  1. Voir WifiNetworkSpecifier.Builder # build () pour le nouveau mécanisme permettant de déclencher la connexion à un réseau Wi-Fi.
  2. Voir addNetworkSuggestions (java.util.List), removeNetworkSuggestions (java.util.List) pour la nouvelle API pour ajouter des réseaux Wi-Fi pour considération lors de la connexion automatique au wifi. Remarque sur la compatibilité: pour les applications ciblant Build.VERSION_CODES.Q ou une version ultérieure, cette API renvoie toujours false.

À partir du niveau 29 de l'API, pour vous connecter au réseau WiFi, vous devrez utiliser WifiNetworkSpecifier. Vous pouvez trouver un exemple de code sur https://developer.android.com/reference/android/net/wifi/WifiNetworkSpecifier.Builder.html#build ()

VIjay J
la source
Est-il possible de se connecter à un réseau WEP avec le nouveau WifiNetWorkSpecifier.Builder? Je ne trouve pas de méthode pour ajouter une phrase de passe WEP au générateur.
Dieter27
Le numéro 1 ne semble pas fonctionner, y a-t-il un rappel?
Faizan Mir
1

J'ai également essayé de me connecter au réseau. Aucune des solutions proposées ci-dessus ne fonctionne pour le hugerock t70. Fonction wifiManager.disconnect (); ne se déconnecte pas du réseau actuel. Par conséquent, vous ne pouvez pas vous reconnecter au réseau spécifié. J'ai modifié le code ci-dessus. Pour moi, le code bolow fonctionne parfaitement:

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);
user1277317
la source
Je reçois une erreur dans 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

Essayez cette méthode. C'est très facile:

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;
    }
}
Hiren Vaghela
la source