如何以编程方式连接Android中的特定Wi-Fi网络?

Vik*_*pta 279 android wifimanager android-wifi

我想设计一个应用程序,显示可用的Wi-Fi网络列表,并连接到用户选择的任何网络.

我已经实现了显示扫描结果的部分.现在,我想从扫描结果列表连接到用户选择的特定网络.

我该怎么做呢?

ken*_*ota 428

你需要创建这样的WifiConfiguration实例:

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

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

然后,对于WEP网络,您需要这样做:

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

对于WPA网络,您需要添加如下所示的密码:

conf.preSharedKey = "\""+ networkPass +"\"";
Run Code Online (Sandbox Code Playgroud)

对于Open network,您需要这样做:

conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
Run Code Online (Sandbox Code Playgroud)

然后,您需要将其添加到Android wifi管理器设置:

WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE); 
wifiManager.addNetwork(conf);
Run Code Online (Sandbox Code Playgroud)

最后,您可能需要启用它,以便Android连接到它:

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;
    }           
 }
Run Code Online (Sandbox Code Playgroud)

UPD:如果是WEP,如果您的密码是十六进制,则不需要用引号括起来.

  • 我忘了提一件事.如果是WEP,如果您的密码是十六进制,则无需用引号括起来. (8认同)
  • 感谢您提供的解决方案,您能详细说明如何检查连接是否成功.例如,用户可能输入了错误的密码,应该通知它. (8认同)
  • 这很好用!谢谢:)但还有一件事我想问.你不需要设置allowedPairwiseCipher,allowedAuthALgorithms和allowedProtocols吗?以及如何确定要设置的特定属性; 就像你为WEP网络设置WEP40 for GroupCipher一样? (5认同)
  • 如果所需的Wifi热点根本不使用任何密码怎么样....我们应该使用.preSharedKey = null; 或者我们应该设置.preSharedKey =""; 哪一个是正确的?@kenota (3认同)
  • 它对我不起作用:它直接重新连接到以前记忆的wifi而不是连接到新的. (3认同)
  • 您可以通过手动连接到网络然后使用Mike代码示例中的readConfig函数来确定要设置哪些属性的一种方法. (2认同)

sea*_*ola 135

刚才的答复工作,但解决的办法其实是可以更简单.当您通过WifiManager添加网络时获得网络ID时,不需要循环通过已配置的网络列表.

因此,完整,简化的解决方案看起来像这样:

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();
Run Code Online (Sandbox Code Playgroud)

  • 应该提一下,需要`CHANGE_WIFI_STATE`权限. (10认同)
  • 根据enableNetwork的javadoc,如果你使用boolean disableOthers为true,那么你不必断开连接或连接,它会为你做两件事 (7认同)
  • 如果没有使用密码。我们应该把 .preSharedKey = null; 或者我们应该只输入空字符串@seanloyola ? (2认同)
  • 如果您已经连接到另一个网络,则@MuhammedRefaat会断开连接。 (2认同)

小智 27

在连接WIFI网络之前,您需要检查WIFI网络的安全类型ScanResult类具有的功能.此字段为您提供网络类型

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

三种类型的WIFI网络.

首先,实例化一个WifiConfiguration对象并填写网络的SSID(注意它必须用双引号括起来),将初始状态设置为disabled,并指定网络的优先级(大约40的数字似乎运行良好).

WifiConfiguration wfc = new WifiConfiguration();

wfc.SSID = "\"".concat(ssid).concat("\"");
wfc.status = WifiConfiguration.Status.DISABLED;
wfc.priority = 40;
Run Code Online (Sandbox Code Playgroud)

现在更复杂的部分:我们需要填写WifiConfiguration的几个成员来指定网络的安全模式.对于开放网络.

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);
Run Code Online (Sandbox Code Playgroud)

对于使用WEP的网络; 请注意,WEP密钥也用双引号括起来.

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;
Run Code Online (Sandbox Code Playgroud)

对于使用WPA和WPA2的网络,我们可以为两者设置相同的值.

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("\"");
Run Code Online (Sandbox Code Playgroud)

最后,我们可以将网络添加到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
} 
Run Code Online (Sandbox Code Playgroud)

  • 我总是得到网络ID -1 (8认同)

Roh*_*wal 17

感谢@ raji-ramamoorthi和@kenota

对我有用的解决方案是此线程中上述贡献者的组合.

为了让ScanResult这里的过程.

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();
            }
        };
Run Code Online (Sandbox Code Playgroud)

请注意,以unregisteronPauseonStop住这unregisterReceiver(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();
        }
    }
Run Code Online (Sandbox Code Playgroud)


小智 11

在 API 级别 29 中,WifiManager.enableNetwork()方法已弃用。根据 Android API 文档(在此处查看):

  1. 请参阅 WifiNetworkSpecifier.Builder#build() 以了解触发连接到 Wi-Fi 网络的新机制。
  2. 请参阅 addNetworkSuggestions(java.util.List)、removeNetworkSuggestions(java.util.List) 以获取新 API,以在自动连接到 wifi 时考虑添加 Wi-Fi 网络。兼容性说明:对于面向 Build.VERSION_CODES.Q 或更高版本的应用程序,此 API 将始终返回 false。

从 API 级别 29 开始,要连接到 WiFi 网络,您需要使用WifiNetworkSpecifier. 您可以在https://developer.android.com/reference/android/net/wifi/WifiNetworkSpecifier.Builder.html#build()找到示例代码

  • #1 也不起作用,设备显示连接到网络的提示,但没有互联网连接。根据文档:“这些说明符只能用于请求本地 wifi 网络(即没有互联网功能)。” — 我无法让 #2 执行任何操作,只显示一个带有“?”的 wifi 图标。 (2认同)

Mar*_*fer 6

如果您的设备知道 Wifi 配置(已存储),我们就可以绕过火箭科学。只需遍历配置检查 SSID 是否匹配。如果是,连接并返回

设置权限:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
Run Code Online (Sandbox Code Playgroud)

连接:

    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;
Run Code Online (Sandbox Code Playgroud)


小智 5

我想明白为什么你对 WPA/WPA2 的回答不起作用……经过数小时的尝试,我发现了你缺少的东西:

conf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
Run Code Online (Sandbox Code Playgroud)

需要 WPA 网络!!!!

现在,它有效:)


归档时间:

查看次数:

284710 次

最近记录:

7 年 前