Làm cách nào để kết nối với mạng Wi-Fi cụ thể trong Android theo chương trình?


294

Tôi muốn thiết kế một ứng dụng hiển thị danh sách các mạng Wi-Fi khả dụng và kết nối với bất kỳ mạng nào được người dùng chọn.

Tôi đã thực hiện phần hiển thị kết quả quét. Bây giờ tôi muốn kết nối với một mạng cụ thể được người dùng chọn từ danh sách kết quả quét.

Làm thế nào để tôi làm điều này?



Điều này làm việc cho tôi WPA2 và WEP: stackoverflow.com/a/29575563/7337517
Kundan

Câu trả lời:


441

Bạn cần tạo WifiConfigurationví dụ như thế này:

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

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

Sau đó, đối với mạng WEP, bạn cần thực hiện việc này:

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

Đối với mạng WPA, bạn cần thêm cụm mật khẩu như thế này:

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

Đối với mạng mở, bạn cần thực hiện việc này:

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

Sau đó, bạn cần thêm nó vào cài đặt trình quản lý wifi Android:

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

Và cuối cùng, bạn có thể cần kích hoạt nó, vì vậy Android kết nối với nó:

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

CẬP NHẬT: Trong trường hợp WEP, nếu mật khẩu của bạn ở dạng hex, bạn không cần phải bao quanh nó bằng dấu ngoặc kép.


5
hoạt động tốt cảm ơn bạn :) nhưng một điều nữa tôi muốn hỏi. Bạn có cần phải thiết lập allowPairwiseCodes, allowAuthAL Thuật và allowProt Protocol không? Và làm thế nào để quyết định thuộc tính cụ thể nào được thiết lập; giống như bạn đặt WEP40 cho GroupCodes cho mạng WEP?
Vikram Gupta

8
Tôi quên đề cập đến một điều. Trong trường hợp của WEP, nếu mật khẩu của bạn ở dạng hex, bạn không cần phải bao quanh nó bằng dấu ngoặc kép.
kenota

8
Cảm ơn giải pháp tốt đẹp, bạn có thể giải thích cách kiểm tra xem kết nối có thành công hay không. Ví dụ, người dùng có thể nhập sai mật khẩu và sẽ được thông báo về nó.
Pascal Klein

3
làm thế nào nếu Điểm truy cập Wifi mong muốn hoàn toàn không sử dụng bất kỳ Mật khẩu nào .... Chúng ta có nên sử dụng .preSharedKey = null; hoặc chúng ta nên đặt .preSharedKey = ""; Cái nào đúng? @kenota
gumuruh

6
Nó không hoạt động đối với tôi: nó kết nối trực tiếp với wifi đã nhớ trước đó thay vì kết nối với mạng mới.
Virthuss

138

Các câu trả lời trước đó làm việc , nhưng các giải pháp thực sự có thể được đơn giản hơn. Không yêu cầu thông qua danh sách mạng được định cấu hình khi bạn nhận id mạng khi bạn thêm mạng thông qua Trình quản lý Wifi.

Vì vậy, giải pháp hoàn chỉnh, đơn giản hóa sẽ trông giống như thế này:

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
nếu mật khẩu không được sử dụng. Chúng ta có nên đặt .preSharedKey = null; hay chúng ta chỉ nên đặt chuỗi rỗng, @seanloyola?
gumuruh

2
@MuhammedRefaat bạn ngắt kết nối khi bạn đã kết nối với mạng khác.
sean loyola

1
@gumuruh bạn hoàn toàn không phải bao gồm đối tượng presharedkey nếu không có khóa bắt buộc.
leanola sean

7
theo javadoc của enableNetwork, nếu bạn sử dụng boolean vô hiệu hóa đúng, thì bạn không phải ngắt kết nối hoặc kết nối, nó sẽ làm cả hai cho bạn
NikkyD 17/03/2015

12
Có lẽ nên đề cập rằng sự CHANGE_WIFI_STATEcho phép là cần thiết.
ThomasW

27

Trước khi kết nối mạng WIFI, bạn cần kiểm tra loại bảo mật của lớp WIFI mạng ScanResult có khả năng. Trường này cung cấp cho bạn loại mạng

Tham khảo: https://developer.android.com/reference/android/net/wifi/ScanResult.html#capabilities

ba loại mạng WIFI.

Đầu tiên, khởi tạo một đối tượng Định cấu hình Wifi và điền SSID của mạng (lưu ý rằng nó phải được đặt trong dấu ngoặc kép), đặt trạng thái ban đầu thành bị tắt và chỉ định mức độ ưu tiên của mạng (số khoảng 40 dường như hoạt động tốt).

WifiConfiguration wfc = new WifiConfiguration();

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

Bây giờ đối với phần phức tạp hơn: chúng ta cần điền vào một số thành viên của WifiConfiguration để chỉ định chế độ bảo mật của mạng. Đối với các mạng mở.

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

Đối với các mạng sử dụng WEP; lưu ý rằng khóa WEP cũng được đặt trong dấu ngoặc kép.

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;

Đối với các mạng sử dụng WPA và WPA2, chúng tôi có thể đặt cùng một giá trị cho một trong hai.

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

Cuối cùng, chúng ta có thể thêm mạng vào danh sách đã biết của Trình quản lý Wifi

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
} 

một lưu ý ưu tiên, trên số điện thoại của tôi khoảng 4000 làm việc. có thể tốt nhất để làm cho phần đó năng động hơn một chút (lặp lại các cấu hình hiện có, v.v.)
Sam

Làm thế nào tôi có thể nhận được loại bảo mật mạng từ SSID cho wifi ScanResult
Shantanu

@shantanu kiểm tra sau để biết chi tiết. stackoverflow.com/questions/6866153/
Mạnh

Trên các thiết bị samsung, cụm mật khẩu được băm chuỗi. Và mã không hoạt động. Bạn có kiểm tra không?
Nguyễn Minh Bình

bạn có thể cung cấp một mẫu để kết nối EAP của loại sim wifi không?
Prashanth Debbadwar

19

Tín dụng cho @ raji-ramamoorthi & @kenota

Giải pháp hiệu quả với tôi là sự kết hợp của những người đóng góp ở trên trong chủ đề này.

Để đến ScanResultđây là quá trình.

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

Để ý đến unregisteronPauseonStopsống cái nàyunregisterReceiver(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

Nếu thiết bị của bạn biết cấu hình Wifi (đã được lưu trữ), chúng ta có thể bỏ qua khoa học tên lửa. Chỉ cần lặp qua các cấu hình kiểm tra xem SSID có khớp không. Nếu vậy, kết nối và trở lại .

Đặt quyền:

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

Kết nối:

    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

Tôi đã vỡ đầu để hiểu tại sao câu trả lời của bạn cho WPA / WPA2 không hoạt động ... sau nhiều giờ thử tôi đã tìm thấy những gì bạn đang thiếu:

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

là BẮT BUỘC cho mạng WPA !!!!

Bây giờ, nó hoạt động :)


4

Đây là một hoạt động bạn có thể phân lớp để buộc kết nối với một wifi cụ thể: https://github.com/zoltanersek/android-wifi-activity/blob/master/app/src/main/java/com/zoltanersek/androidwifiactivity/ WifiActivity.java

Bạn sẽ cần phải phân lớp hoạt động này và thực hiện các phương thức của nó:

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";
  }
}

liên kết xuống bạn có thể cung cấp cho cái mới?
Bắt đầu mã hóa

4

Trong API cấp 29, WifiManager.enableNetwork()phương thức không được dùng nữa . Theo tài liệu API Android (kiểm tra tại đây ):

  1. Xem WifiNetworkSpecifier.Builder # build () để biết cơ chế mới để kích hoạt kết nối với mạng Wi-Fi.
  2. Xem addNetworkSuggestions (java.util.List), removeNetworkSuggestions (java.util.List) để biết API mới để thêm mạng Wi-Fi để xem xét khi tự động kết nối với wifi. Lưu ý về tính tương thích: Đối với các ứng dụng nhắm mục tiêu Build.VERSION_CODES.Q trở lên, API này sẽ luôn trả về sai.

Từ API cấp 29, để kết nối với mạng WiFi, bạn sẽ cần sử dụng WifiNetworkSpecifier. Bạn có thể tìm thấy mã ví dụ tại https://developer.android.com/reference/android/net/wifi/WifiNetworkSpecifier.Builder.html#build ()


Có thể kết nối với mạng WEP với WifiNetWorkSpecifier.Builder mới không? Tôi không thể tìm thấy một phương thức để thêm cụm mật khẩu WEP vào trình xây dựng.
Dieter27

Số 1 dường như không hoạt động là có gọi lại cho nó không?
Faizan Mir

1

Tôi cũng đã cố gắng kết nối với mạng. Không có giải pháp nào được đề xuất ở trên hoạt động cho hugerock t70. Chức năng wifiManager.disconnect (); không ngắt kết nối với mạng hiện tại. Do đó, không thể kết nối lại với mạng được chỉ định. Tôi đã sửa đổi mã trên. Đối với tôi mã bolow hoạt động hoàn hảo:

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

Tôi gặp lỗi trong 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

Hãy thử phương pháp này. Nó rất dễ:

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;
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.