Bagaimana cara saya terhubung ke jaringan Wi-Fi tertentu di Android secara terprogram?

294

Saya ingin merancang aplikasi yang menampilkan daftar jaringan Wi-Fi yang tersedia dan terhubung ke jaringan mana saja yang dipilih oleh pengguna.

Saya telah mengimplementasikan bagian yang menunjukkan hasil pemindaian. Sekarang saya ingin terhubung ke jaringan tertentu yang dipilih oleh pengguna dari daftar hasil pemindaian.

Bagaimana saya melakukan ini?

Vikram Gupta
sumber

Jawaban:

441

Anda perlu membuat WifiConfigurationcontoh seperti ini:

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

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

Kemudian, untuk jaringan WEP Anda perlu melakukan ini:

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

Untuk jaringan WPA Anda perlu menambahkan frasa sandi seperti ini:

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

Untuk jaringan Terbuka Anda perlu melakukan ini:

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

Kemudian, Anda perlu menambahkannya ke pengaturan Android wifi manager:

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

Dan akhirnya, Anda mungkin perlu mengaktifkannya, sehingga Android terhubung ke sana:

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: Dalam hal WEP, jika kata sandi Anda dalam hex, Anda tidak perlu mengelilinginya dengan tanda kutip.

kenota
sumber
5
itu bekerja dengan baik! terima kasih :) tetapi satu hal lagi yang ingin saya tanyakan. Tidakkah Anda perlu mengatur diizinkanPairwiseCipher, allowedAuthALgorithms dan allowedProtocols? Dan bagaimana memutuskan atribut mana yang akan ditetapkan; seperti Anda mengatur WEP40 untuk GroupCipher untuk jaringan WEP?
Vikram Gupta
8
Saya lupa menyebutkan satu hal. Dalam hal WEP, jika kata sandi Anda dalam hex, Anda tidak perlu mengelilinginya dengan tanda kutip.
kenota
8
Terima kasih atas solusinya, bisakah Anda menguraikan cara memeriksa apakah koneksi berhasil atau tidak. Misalnya pengguna mungkin memasukkan kata sandi yang salah dan harus diberitahu tentang itu.
Pascal Klein
3
bagaimana jika Wifi Hotspot yang diinginkan tidak menggunakan kata sandi sama sekali .... Jika kita menggunakan .preSharedKey = null; atau haruskah kita mengatur .preSharedKey = ""; Yang mana yang benar? @kenota
gumuruh
6
Ini tidak bekerja untuk saya: itu menghubungkan kembali langsung ke wifi yang diingat sebelumnya daripada menghubungkan ke yang baru.
Virthuss
138

The jawaban sebelumnya bekerja , tetapi solusi sebenarnya bisa lebih sederhana. Looping melalui daftar jaringan yang dikonfigurasi tidak diperlukan karena Anda mendapatkan id jaringan ketika Anda menambahkan jaringan melalui WifiManager.

Jadi solusi lengkap dan disederhanakan akan terlihat seperti ini:

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
sumber
1
jika kata sandi tidak digunakan. Haruskah kita meletakkan .preSharedKey = null; atau haruskah kita hanya memasukkan string kosong, @seanloyola?
gumuruh
2
@MuhammedRefaat Anda putuskan jika Anda sudah terhubung ke jaringan lain.
sean loyola
1
@gumuruh Anda tidak perlu menyertakan objek presharedkey sama sekali jika tidak ada kunci yang diperlukan.
sean loyola
7
menurut javadoc dari enableNetwork, jika Anda menggunakan boolean disableOthers true, maka Anda tidak perlu memutus atau menyambungkan, itu akan melakukan keduanya untuk Anda
NikkyD
12
Mungkin harus menyebutkan bahwa CHANGE_WIFI_STATEizin diperlukan.
ThomasW
27

Sebelum menghubungkan jaringan WIFI Anda perlu memeriksa jenis keamanan jaringan WIFI kelas ScanResult memiliki kemampuan. Bidang ini memberi Anda jenis jaringan

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

Ada tiga jenis jaringan WIFI.

Pertama, instantiate objek WifiConfiguration dan isi SSID jaringan (perhatikan bahwa itu harus dilampirkan dalam tanda kutip ganda), atur status awal untuk dinonaktifkan, dan tentukan prioritas jaringan (angka sekitar 40 tampaknya berfungsi dengan baik).

WifiConfiguration wfc = new WifiConfiguration();

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

Sekarang untuk bagian yang lebih rumit: kita perlu mengisi beberapa anggota WifiConfiguration untuk menentukan mode keamanan jaringan. Untuk jaringan terbuka.

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

Untuk jaringan yang menggunakan WEP; perhatikan bahwa kunci WEP juga terlampir dalam tanda kutip ganda.

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;

Untuk jaringan yang menggunakan WPA dan WPA2, kami dapat menetapkan nilai yang sama untuk keduanya.

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

Akhirnya, kita dapat menambahkan jaringan ke daftar WifiManager yang dikenal

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
sumber
catatan tentang prioritas, pada nomor telepon saya sekitar 4000 bekerja. mungkin yang terbaik untuk membuat bagian itu sedikit lebih dinamis (beralih konfigurasi yang ada, dll.)
Sam
Bagaimana saya bisa mendapatkan jaringan jenis keamanan dari SSID untuk wifi scanresult
shantanu
@shantanu periksa detail berikut. stackoverflow.com/questions/6866153/…
Kalpesh Gohel
Pada perangkat samsung, frasa sandi adalah string hash. Dan kode tidak berfungsi. Apakah Anda memeriksanya?
Nguyen Minh Binh
dapatkah Anda memberikan sampel untuk menghubungkan EAP wifi tipe sim?
Prashanth Debbadwar
19

Kredit ke @ raji-ramamoorthi & @kenota

Solusi yang bekerja untuk saya adalah kombinasi dari kontributor di atas di utas ini.

Untuk sampai di ScanResultsini adalah prosesnya.

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

Pemberitahuan kepada unregisterpada onPause& onStophidup iniunregisterReceiver(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
sumber
5

Jika perangkat Anda mengetahui konfigurasi Wifi (sudah tersimpan), kami dapat memintas ilmu roket. Hanya loop melalui konfigurasi cek jika SSID cocok. Jika demikian, hubungkan dan kembali .

Tetapkan izin:

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

Menghubung:

    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
sumber
5

Saya mematahkan kepala untuk memahami mengapa jawaban Anda untuk WPA / WPA2 tidak berfungsi ... setelah beberapa jam mencoba, saya menemukan apa yang Anda lewatkan:

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

DIBUTUHKAN untuk jaringan WPA !!!!

Sekarang berhasil :)

Taras Okunev
sumber
4

Ini adalah kegiatan yang dapat Anda subclass untuk memaksa koneksi ke wifi tertentu: https://github.com/zoltanersek/android-wifi-activity/blob/master/app/src/main/java/com/zoltanersek/androidwifiactivity/ WifiActivity.java

Anda perlu mensubklasifikasikan kegiatan ini dan menerapkan metode-metodenya:

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
sumber
Tautan ke bawah dapatkah Anda memberikan yang baru?
StartCoding
4

Di API level 29, WifiManager.enableNetwork()metode tidak digunakan lagi . Sesuai dokumentasi Android API (periksa di sini ):

  1. Lihat WifiNetworkSpecifier.Builder # build () untuk mekanisme baru untuk memicu koneksi ke jaringan Wi-Fi.
  2. Lihat addNetworkSuggestions (java.util.List), hapusNetworkSuggestions (java.util.List) untuk API baru untuk menambahkan jaringan Wi-Fi untuk dipertimbangkan ketika menghubungkan otomatis ke wifi. Catatan Kompatibilitas: Untuk aplikasi yang menargetkan Build.VERSION_CODES.Q atau lebih tinggi, API ini akan selalu kembali salah.

Dari API level 29, untuk terhubung ke jaringan WiFi, Anda harus menggunakannya WifiNetworkSpecifier. Anda dapat menemukan kode contoh di https://developer.android.com/reference/android/net/wifi/WifiNetworkSpecifier.Builder.html#build ()

VIjay J
sumber
Apakah mungkin untuk terhubung ke jaringan WEP dengan WifiNetWorkSpecifier.Builder baru? Saya tidak dapat menemukan metode untuk menambahkan frasa sandi WEP ke pembangun.
Dieter27
Nomor 1 sepertinya tidak berfungsi apakah ada panggilan balik untuk itu?
Faizan Mir
1

Saya juga mencoba terhubung ke jaringan. Tidak ada solusi yang diusulkan di atas yang berfungsi untuk hugerock T70. Fungsi wifiManager.disconnect (); tidak terputus dari jaringan saat ini. Oleh karena itu tidak dapat menyambung kembali ke jaringan yang ditentukan. Saya telah memodifikasi kode di atas. Bagi saya bolow kode berfungsi dengan baik:

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);
pengguna1277317
sumber
Saya mendapatkan kesalahan di 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

Coba metode ini. Sangat mudah:

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
sumber