我想设计一个应用程序,显示可用的Wi-Fi网络列表,并连接到用户选择的任何网络 .
我已经实现了显示扫描结果的部分 . 现在,我想从扫描结果列表连接到用户选择的特定网络 .
我该怎么做呢?
您需要像这样创建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,如果您的密码是十六进制,则不需要用引号括起来 .
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();
在连接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 }
感谢@ raji-ramamoorthi和@kenota
对我有用的解决方案是此线程中上述贡献者的组合 .
要获得 ScanResult ,这是一个过程 .
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 它在 onPause & onStop 住这个 unregisterReceiver(broadcastReceiver);
unregister
onPause
onStop
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(); } }
这是一个可以子类强制连接到特定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"; } }
如果您的设备知道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;
我弄清楚了解为什么你对WPA / WPA2的答案不起作用......经过数小时的尝试后我发现了你所缺少的东西:
conf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
WPA网络需要!!!!
现在,它的工作原理:)
我也尝试连接到网络 . 上面提出的解决方案都不适用于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);
试试这个方法 . 这很容易:
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; } }
/** * @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(); }
10 回答
您需要像这样创建WifiConfiguration实例:
然后,对于WEP网络,您需要这样做:
对于WPA网络,您需要添加如下的密码:
对于Open network,您需要这样做:
然后,您需要将其添加到Android wifi管理器设置:
最后,您可能需要启用它,以便Android连接到它:
UPD:如果是WEP,如果您的密码是十六进制,则不需要用引号括起来 .
earlier answer works,但解决方案实际上可以更简单 . 当您通过WifiManager添加网络时获得网络ID时,不需要循环通过已配置的网络列表 .
因此,完整,简化的解决方案看起来像这样:
参考:https://developer.android.com/reference/android/net/wifi/ScanResult.html#capabilities
有三种类型的WIFI网络 .
首先,实例化一个WifiConfiguration对象并填写网络的SSID(注意它必须用双引号括起来),将初始状态设置为disabled,并指定网络的优先级(大约40的数字似乎运行良好) .
现在更复杂的部分:我们需要填写WifiConfiguration的几个成员来指定网络的安全模式 . 对于开放网络 .
对于使用WEP的网络;请注意,WEP密钥也用双引号括起来 .
对于使用WPA和WPA2的网络,我们可以为两者设置相同的值 .
最后,我们可以将网络添加到WifiManager的已知列表中
感谢@ raji-ramamoorthi和@kenota
对我有用的解决方案是此线程中上述贡献者的组合 .
要获得
ScanResult
,这是一个过程 .通知
unregister
它在onPause
&onStop
住这个unregisterReceiver(broadcastReceiver);
这是一个可以子类强制连接到特定wifi的活动:https://github.com/zoltanersek/android-wifi-activity/blob/master/app/src/main/java/com/zoltanersek/androidwifiactivity/WifiActivity.java
您将需要子类化此活动并实现其方法:
如果您的设备知道Wifi配置(已经存储),我们可以绕过火箭科学 . 只需循环配置,检查SSID是否匹配 . 如果是这样,请连接并 return .
设置权限:
连接:
我弄清楚了解为什么你对WPA / WPA2的答案不起作用......经过数小时的尝试后我发现了你所缺少的东西:
WPA网络需要!!!!
现在,它的工作原理:)
我也尝试连接到网络 . 上面提出的解决方案都不适用于hugerock t70 . 函数wifiManager.disconnect();不会断开与当前网络的连接 . 因此无法重新连接到指定的网络 . 我修改了上面的代码 . 对我来说,代码bolow完美地工作:
试试这个方法 . 这很容易: