Android'de belirli bir Kablosuz ağa programlı olarak nasıl bağlanırım?


294

Kullanılabilir Wi-Fi ağlarının listesini gösteren ve kullanıcı tarafından seçilen ağa bağlanmak için bir uygulama tasarlamak istiyorum.

Tarama sonuçlarını gösteren kısmı uyguladım. Şimdi tarama sonuçları listesinden kullanıcı tarafından seçilen belirli bir ağa bağlanmak istiyorum.

Bunu nasıl yaparım?



Bu benim için çalıştı WPA2 ve WEP: stackoverflow.com/a/29575563/7337517
Kundan

Yanıtlar:


441

Bunun WifiConfigurationgibi bir örnek oluşturmanız gerekir :

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

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

Ardından, WEP ağı için bunu yapmanız gerekir:

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

WPA ağı için şöyle bir parola eklemeniz gerekir:

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

Açık ağ için şunları yapmanız gerekir:

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

Ardından, Android wifi yöneticisi ayarlarına eklemeniz gerekir:

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

Son olarak, etkinleştirmeniz gerekebilir, böylece Android ona bağlanır:

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: WEP durumunda, şifreniz onaltılıksa, tırnak işareti içine almanıza gerek yoktur.


5
iyi çalışıyor! teşekkür ederim :) ama bir şey daha sormak istiyorum. AllowedPairwiseCipher, allowedAuthALgorithms ve allowedProtocols ayarlamanız gerekmiyor mu? Ve hangi belirli özelliğin ayarlanacağına nasıl karar verilir; WEP ağları için GroupCipher için WEP40'ı nasıl ayarladınız?
Vikram Gupta

8
Bir şeyden bahsetmeyi unuttum. WEP durumunda, şifreniz onaltılıksa, tırnak işareti içine almanıza gerek yoktur.
kenota

8
Güzel çözüm için teşekkürler, bağlantının başarılı olup olmadığını nasıl kontrol edeceğinizi açıklayabilir misiniz? Örneğin, kullanıcı yanlış şifre girebilir ve bu konuda bilgilendirilmelidir.
Pascal Klein

3
İstenilen Wifi Hotspot herhangi bir Parola kullanmıyorsa .... .preSharedKey = null; veya .preSharedKey = "" ayarlamalıyız; Hangisi doğru? @kenota
gumuruh

6
Benim için çalışmıyor: yenisine bağlanmak yerine doğrudan önceki hatırlanan wifi'ye yeniden bağlanıyor.
Virthuss

138

Daha önceki cevap işe yarıyor , ancak çözüm aslında daha basit olabilir. Ağı WifiManager üzerinden eklediğinizde ağ kimliğini aldığınız için yapılandırılmış ağlar listesinde dolaşmak gerekli değildir.

Böylece, eksiksiz ve basitleştirilmiş çözüm şöyle görünecektir:

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
şifre kullanılmazsa. .PreSharedKey = null; yoksa boş bir dize mi koymalıyız, seanloyola?
Gumuruh

2
@MuhammedRefaat, başka bir ağa bağlı olmanız durumunda bağlantıyı kesersiniz.
sean loyola

1
@gumuruh, gerekli anahtar yoksa, önceden paylaşılan anahtar nesnesini eklemeniz gerekmez.
sean loyola

7
enableNetwork javadocuna göre, eğer boole enableOthers true kullanırsanız, bağlantıyı kesmeniz veya bağlanmanız gerekmez, her ikisi de sizin için yapılacaktır
NikkyD

12
Muhtemelen CHANGE_WIFI_STATEiznin gerekli olduğunu belirtmelidir .
ThomasW

27

WIFI ağını bağlamadan önce ScanResult sınıfının WIFI ağının güvenlik türünü kontrol etmeniz gerekir. Bu alan size ağ türünü verir

Bakınız: https://developer.android.com/reference/android/net/wifi/ScanResult.html#capability

Orada üç tip WIFI ağlarının.

İlk olarak, bir WifiConfiguration nesnesini başlatın ve ağın SSID'sini doldurun (çift tırnak içine alınmalıdır), başlangıç ​​durumunu devre dışı olarak ayarlayın ve ağın önceliğini belirtin (40 civarında rakamlar iyi çalışıyor gibi görünüyor).

WifiConfiguration wfc = new WifiConfiguration();

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

Şimdi daha karmaşık kısım için: Ağın güvenlik modunu belirtmek için WifiConfiguration'ın birkaç üyesini doldurmamız gerekiyor. Açık ağlar için.

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

WEP kullanan ağlar için; WEP anahtarının çift tırnak içine alındığını unutmayın.

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;

WPA ve WPA2 kullanan ağlar için her ikisi için de aynı değerleri ayarlayabiliriz.

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

Son olarak, ağı WifiManager'ın bilinen listesine ekleyebiliriz

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
} 

öncelik hakkında bir not, 4000 civarında telefon numaralarında çalıştı. Bu bölümü biraz daha dinamik hale getirmek için en iyisi (mevcut yapılandırmaları tekrarlayın)
Sam

WiFi ScanResult için SSID'den ağ güvenliği türünü nasıl alabilirim
shantanu

@shantanu detay için aşağıdakileri kontrol edin. stackoverflow.com/questions/6866153/…
Kalpesh Gohel

Samsung cihazlarda parola karma dizgidir. Ve kod çalışmıyor. Bunu kontrol ediyor musun?
Nguyen Minh Binh

sim tipi wifi EAP bağlamak için bir örnek sağlayabilir?
Prashanth Debbadwar

19

@ Raji-ramamoorthi & @kenota'ya teşekkür ederiz

Benim için çalışan çözüm, bu konudaki yukarıdaki katılımcıların birleşimidir.

Buraya gelmek ScanResultsüreç.

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

İçin Bildirimi unregisterüzerine kendisine onPauseve onStopcanlı buunregisterReceiver(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

Cihazınız Wifi yapılandırmalarını (önceden kaydedilmiş) biliyorsa, roket bilimini atlayabiliriz. SSID'nin eşleşip eşleşmediğini bir yapılandırmada yapılandırın. Öyleyse bağlayın ve geri dönün .

İzinleri ayarlayın:

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

connect:

    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

WPA / WPA2 için cevaplarınızın neden çalışmadığını anlamak için kafamı kırdım ... saatlerce denemeden sonra eksik olanı buldum:

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

WPA ağları için GEREKLİDİR !!!!

Şimdi çalışıyor :)


4

Bu, belirli bir kablosuz ağa bağlanmaya zorlamak için alt sınıf oluşturabileceğiniz bir etkinliktir: https://github.com/zoltanersek/android-wifi-activity/blob/master/app/src/main/java/com/zoltanersek/androidwifiactivity/ WifiActivity.java

Bu etkinliği alt sınıflandırmanız ve yöntemlerini uygulamanız gerekir:

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 yenisini verebilir misiniz?
StartCoding

4

API düzey 29'da WifiManager.enableNetwork()yöntem kullanımdan kaldırılmıştır . Android API dokümanlarına göre ( buraya bakın ):

  1. Bir Wi-Fi ağına bağlantıyı tetikleyen yeni mekanizma için bkz. WifiNetworkSpecifier.Builder # build ().
  2. Kablosuz ağa otomatik bağlanırken dikkate alınması gereken Wi-Fi ağlarını eklemek için yeni API için addNetworkSuggestions (java.util.List), removeNetworkSuggestions (java.util.List) sayfasına bakın. Uyumluluk Not: Build.VERSION_CODES.Q veya daha üstünü hedefleyen uygulamalar için bu API her zaman false değerini döndürür.

API düzey 29'dan WiFi ağına bağlanmak için kullanmanız gerekir WifiNetworkSpecifier. Örnek kodu https://developer.android.com/reference/android/net/wifi/WifiNetworkSpecifier.Builder.html#build () adresinde bulabilirsiniz.


Yeni WifiNetWorkSpecifier.Builder ile bir WEP ağına bağlanmak mümkün mü? Oluşturucuya WEP parolası eklemek için bir yöntem bulamıyorum.
Dieter27

1 Numara işe yaramıyor gibi görünüyor herhangi bir geri arama var mı?
Faizan Mir

1

Ayrıca ağa bağlanmaya çalıştım. Yukarıda önerilen çözümlerin hiçbiri hugerock t70 için geçerli değildir. WifiManager.disconnect () işlevi; mevcut ağ ile olan bağlantısı kesilmez. Bu nedenle belirtilen ağa yeniden bağlanamaz. Yukarıdaki kodu değiştirdim. Benim için kod bolow mükemmel çalışıyor:

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

Android 10'da bir hata alıyorum: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

Bu yöntemi deneyin. Bu çok kolay:

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;
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.