首页 文章

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

提问于
浏览
270

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

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

我该怎么做呢?

10 回答

  • 131

    您需要像这样创建WifiConfiguration实例:

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

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

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

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

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

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

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

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

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

    最后,您可能需要启用它,以便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;
        }           
     }
    

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

  • 1

    earlier answer works,但解决方案实际上可以更简单 . 当您通过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();
    
  • 4

    在连接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;
    

    现在更复杂的部分:我们需要填写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);
    

    对于使用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;
    

    对于使用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("\"");
    

    最后,我们可以将网络添加到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
    }
    
  • 419

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

    通知 unregister 它在 onPauseonStop 住这个 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();
            }
        }
    
  • 3

    这是一个可以子类化以强制连接到特定wifi的活动:https://github.com/zoltanersek/android-wifi-activity/blob/master/app/src/main/java/com/zoltanersek/androidwifiactivity/WifiActivity.java

    您将需要子类化此活动并实现其方法:

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

    如果您的设备知道Wifi配置(已经存储),我们可以绕过火箭科学 . 只需循环配置,检查SSID是否匹配 . 如果是这样,请连接和 return .

    设置权限:

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

    连接:

    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;
    
  • 16

    我弄清楚了解为什么你的WPA / WPA2的答案不起作用......经过数小时的尝试后我发现了你所缺少的东西:

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

    WPA网络需要!!!!

    现在,它工作:)

  • 0

    我也尝试连接到网络 . 上面提出的解决方案都不适用于hugerock t70 . 函数wifiManager.disconnect();不会断开与当前网络的连接 . 因此无法重新连接到指定的网络 . 我修改了上面的代码 . 对我来说,代码bolow完美地工作:

    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 +"\"";
    
    conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
    
    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);
    
  • 0

    试试这个方法 . 这很容易:

    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;
        }
    }
    
  • 27
    /**
         * @param context Context
         * @return true if device is connected to Internet
         */
        public static boolean isNetworkConnected(Context context) {
    
            ConnectivityManager cm =
                    (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
            assert cm != null;
            NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
            return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
        }
    

相关问题