package com.sunvote.xpadapp.utils; import java.util.Comparator; import java.util.List; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiConfiguration.AuthAlgorithm; import android.net.wifi.WifiConfiguration.GroupCipher; import android.net.wifi.WifiConfiguration.KeyMgmt; import android.net.wifi.WifiConfiguration.PairwiseCipher; import android.net.wifi.WifiConfiguration.Protocol; import android.net.wifi.WifiManager; import android.text.TextUtils; import android.util.Log; import com.sunvote.util.LogUtil; import com.sunvote.util.StringUtils; /** * Created by Elvis on 2017/12/13 14:13 * Email:Eluis@psunsky.com * 版权所有:长沙中天电子设计开发有限公司 * Description: 人大通用版XPadAppRD */ public class WiFi { // Constants used for different security types public static final String WPA2 = "WPA2"; public static final String WPA = "WPA"; public static final String WEP = "WEP"; public static final String OPEN = "Open"; // For EAP Enterprise fields public static final String WPA_EAP = "WPA-EAP"; public static final String IEEE8021X = "IEEE8021X"; public static final String[] EAP_METHOD = {"PEAP", "TLS", "TTLS"}; public static final int WEP_PASSWORD_AUTO = 0; public static final int WEP_PASSWORD_ASCII = 1; public static final int WEP_PASSWORD_HEX = 2; private static final String TAG = "Wifi Connecter"; /** * Change the password of an existing configured network and connect to it * * @param wifiMgr * @param config * @param newPassword * @return */ public static boolean changePasswordAndConnect(final WifiManager wifiMgr, final WifiConfiguration config, final String newPassword, final int numOpenNetworksKept) { setupSecurity(config, getWifiConfigurationSecurity(config), newPassword); final int networkId = wifiMgr.updateNetwork(config); if (networkId == -1) { // Update failed. return false; } //确定 return connectToConfiguredNetwork(wifiMgr, config, true); } /** * Configure a network, and connect to it. * * @param wifiMgr * @param scanResult * @param password Password for secure network or is ignored. * @return */ public static boolean connectToNewNetwork(final WifiManager wifiMgr, final ScanResult scanResult, final String password) { //1.获取wifi加密方式(WEP, WPA, WPA2, WPA_EAP, IEEE8021X) final String security = getScanResultSecurity(scanResult); LogUtil.i(TAG,"connectWifi ,security:" + security + ",ssid:" + scanResult.SSID + ",password:" + password); if (security.equals(OPEN)) { final int numOpenNetworksKept = 10; checkForExcessOpenNetworkAndSave(wifiMgr, numOpenNetworksKept); } WifiConfiguration config = new WifiConfiguration(); config.SSID = StringUtils.convertToQuotedString(scanResult.SSID); config.BSSID = scanResult.BSSID; setupSecurity(config, security, password); int id = wifiMgr.addNetwork(config); if (id == -1) { return false; } if (!wifiMgr.saveConfiguration()) { return false; } config = getWifiConfiguration(wifiMgr, config, security); if (config == null) { return false; } return connectToConfiguredNetwork(wifiMgr, config, true); } /** * Configure a network, and connect to it. * * @param wifiMgr * @param password Password for secure network or is ignored. * @return */ public static boolean connectToNewNetwork(final WifiManager wifiMgr,final String security ,final String ssid, final String password) { //1.获取wifi加密方式(WEP, WPA, WPA2, WPA_EAP, IEEE8021X) if (security.equals(OPEN)) { final int numOpenNetworksKept = 10; checkForExcessOpenNetworkAndSave(wifiMgr, numOpenNetworksKept); } WifiConfiguration config = new WifiConfiguration(); config.SSID = StringUtils.convertToQuotedString(ssid); // config.BSSID = ssid; setupSecurity(config, security, password); int id = wifiMgr.addNetwork(config); if (id == -1) { return false; } if (!wifiMgr.saveConfiguration()) { return false; } config = getWifiConfiguration(wifiMgr, config, security); if (config == null) { return false; } return connectToConfiguredNetwork(wifiMgr, config, true); } /** * Connect to a configured network. * * @param config * @return */ public static boolean connectToConfiguredNetwork(final WifiManager wifiMgr, WifiConfiguration config, boolean reassociate) { final String security = getWifiConfigurationSecurity(config); int oldPri = config.priority; // Make it the highest priority. int newPri = getMaxPriority(wifiMgr) + 1; if (newPri > MAX_PRIORITY) { newPri = shiftPriorityAndSave(wifiMgr); config = getWifiConfiguration(wifiMgr, config, security); if (config == null) { return false; } } // Set highest priority to this configured network config.priority = newPri; int networkId = wifiMgr.updateNetwork(config); if (networkId == -1) { return false; } // Do not disable others if (!wifiMgr.enableNetwork(networkId, false)) { config.priority = oldPri; return false; } if (!wifiMgr.saveConfiguration()) { config.priority = oldPri; return false; } // We have to retrieve the WifiConfiguration after save. config = getWifiConfiguration(wifiMgr, config, security); if (config == null) { return false; } // Disable others, but do not save. // Just to force the WifiManager to connect to it. if (!wifiMgr.enableNetwork(config.networkId, true)) { return false; } final boolean connect = reassociate ? wifiMgr.reassociate() : wifiMgr.reconnect(); if (!connect) { return false; } return true; } private static void sortByPriority(final List configurations) { java.util.Collections.sort(configurations, new Comparator() { @Override public int compare(WifiConfiguration object1, WifiConfiguration object2) { return object1.priority - object2.priority; } }); } /** * Ensure no more than numOpenNetworksKept open networks in configuration list. * * @param wifiMgr * @param numOpenNetworksKept * @return Operation succeed or not. */ private static boolean checkForExcessOpenNetworkAndSave(final WifiManager wifiMgr, final int numOpenNetworksKept) { final List configurations = wifiMgr.getConfiguredNetworks(); sortByPriority(configurations); boolean modified = false; int tempCount = 0; for (int i = configurations.size() - 1; i >= 0; i--) { final WifiConfiguration config = configurations.get(i); if (getWifiConfigurationSecurity(config).equals(OPEN)) { tempCount++; if (tempCount >= numOpenNetworksKept) { modified = true; wifiMgr.removeNetwork(config.networkId); } } } if (modified) { return wifiMgr.saveConfiguration(); } return true; } private static final int MAX_PRIORITY = 99999; private static int shiftPriorityAndSave(final WifiManager wifiMgr) { final List configurations = wifiMgr.getConfiguredNetworks(); sortByPriority(configurations); final int size = configurations.size(); for (int i = 0; i < size; i++) { final WifiConfiguration config = configurations.get(i); config.priority = i; wifiMgr.updateNetwork(config); } wifiMgr.saveConfiguration(); return size; } private static int getMaxPriority(final WifiManager wifiManager) { final List configurations = wifiManager.getConfiguredNetworks(); int pri = 0; for (final WifiConfiguration config : configurations) { if (config.priority > pri) { pri = config.priority; } } return pri; } public static WifiConfiguration getWifiConfiguration(final WifiManager wifiMgr, final ScanResult hotsopt, String hotspotSecurity) { final String ssid = StringUtils.convertToQuotedString(hotsopt.SSID); if (ssid.length() == 0) { return null; } final String bssid = hotsopt.BSSID; if (bssid == null) { return null; } if (hotspotSecurity == null) { hotspotSecurity = getScanResultSecurity(hotsopt); } final List configurations = wifiMgr.getConfiguredNetworks(); for (final WifiConfiguration config : configurations) { if (config.SSID == null || !ssid.equals(config.SSID)) { continue; } if (config.BSSID == null || bssid.equals(config.BSSID)) { final String configSecurity = getWifiConfigurationSecurity(config); if (hotspotSecurity.equals(configSecurity)) { return config; } } } return null; } public static WifiConfiguration getWifiConfiguration(final WifiManager wifiMgr, final WifiConfiguration configToFind, String security) { final String ssid = configToFind.SSID; if (ssid.length() == 0) { return null; } final String bssid = configToFind.BSSID; if (security == null) { security = getWifiConfigurationSecurity(configToFind); } final List configurations = wifiMgr.getConfiguredNetworks(); for (final WifiConfiguration config : configurations) { if (config.SSID == null || !ssid.equals(config.SSID)) { continue; } if (config.BSSID == null || bssid == null || bssid.equals(config.BSSID)) { final String configSecurity = getWifiConfigurationSecurity(config); if (security.equals(configSecurity)) { return config; } } } return null; } /** * @return The security of a given {@link WifiConfiguration}. */ static public String getWifiConfigurationSecurity(WifiConfiguration wifiConfig) { if (wifiConfig.allowedKeyManagement.get(KeyMgmt.NONE)) { // If we never set group ciphers, wpa_supplicant puts all of them. // For open, we don't set group ciphers. // For WEP, we specifically only set WEP40 and WEP104, so CCMP // and TKIP should not be there. if (!wifiConfig.allowedGroupCiphers.get(GroupCipher.CCMP) && (wifiConfig.allowedGroupCiphers.get(GroupCipher.WEP40) || wifiConfig.allowedGroupCiphers.get(GroupCipher.WEP104))) { return WEP; } else { return OPEN; } } else if (wifiConfig.allowedProtocols.get(Protocol.RSN)) { return WPA2; } else if (wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_EAP)) { return WPA_EAP; } else if (wifiConfig.allowedKeyManagement.get(KeyMgmt.IEEE8021X)) { return IEEE8021X; } else if (wifiConfig.allowedProtocols.get(Protocol.WPA)) { return WPA; } else { Log.w(TAG, "Unknown security type from WifiConfiguration, falling back on open."); return OPEN; } } /** * Fill in the security fields of WifiConfiguration config. * * @param config The object to fill. * @param security If is OPEN, password is ignored. * @param password Password of the network if security is not OPEN. */ static private void setupSecurity(WifiConfiguration config, String security, final String password) { config.allowedAuthAlgorithms.clear(); config.allowedGroupCiphers.clear(); config.allowedKeyManagement.clear(); config.allowedPairwiseCiphers.clear(); config.allowedProtocols.clear(); if (TextUtils.isEmpty(security)) { security = OPEN; Log.w(TAG, "Empty security, assuming open"); } if (security.equals(WEP)) { int wepPasswordType = WEP_PASSWORD_AUTO; // If password is empty, it should be left untouched if (!TextUtils.isEmpty(password)) { if (wepPasswordType == WEP_PASSWORD_AUTO) { if (isHexWepKey(password)) { config.wepKeys[0] = password; } else { config.wepKeys[0] = StringUtils.convertToQuotedString(password); } } else { config.wepKeys[0] = wepPasswordType == WEP_PASSWORD_ASCII ? StringUtils.convertToQuotedString(password) : password; } } config.wepTxKeyIndex = 0; config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN); config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED); config.allowedKeyManagement.set(KeyMgmt.NONE); config.allowedGroupCiphers.set(GroupCipher.WEP40); config.allowedGroupCiphers.set(GroupCipher.WEP104); } else if (security.equals(WPA) || security.equals(WPA2)) { config.allowedGroupCiphers.set(GroupCipher.TKIP); config.allowedGroupCiphers.set(GroupCipher.CCMP); config.allowedKeyManagement.set(KeyMgmt.WPA_PSK); config.allowedPairwiseCiphers.set(PairwiseCipher.CCMP); config.allowedPairwiseCiphers.set(PairwiseCipher.TKIP); config.allowedProtocols.set(security.equals(WPA2) ? Protocol.RSN : Protocol.WPA); // If password is empty, it should be left untouched if (!TextUtils.isEmpty(password)) { if (password.length() == 64 && isHex(password)) { // Goes unquoted as hex config.preSharedKey = password; } else { // Goes quoted as ASCII config.preSharedKey = StringUtils.convertToQuotedString(password); } } } else if (security.equals(OPEN)) { config.allowedKeyManagement.set(KeyMgmt.NONE); } else if (security.equals(WPA_EAP) || security.equals(IEEE8021X)) { config.allowedGroupCiphers.set(GroupCipher.TKIP); config.allowedGroupCiphers.set(GroupCipher.CCMP); if (security.equals(WPA_EAP)) { config.allowedKeyManagement.set(KeyMgmt.WPA_EAP); } else { config.allowedKeyManagement.set(KeyMgmt.IEEE8021X); } if (!TextUtils.isEmpty(password)) { config.preSharedKey = StringUtils.convertToQuotedString(password); } } } private static boolean isHexWepKey(String wepKey) { final int len = wepKey.length(); // WEP-40, WEP-104, and some vendors using 256-bit WEP (WEP-232?) if (len != 10 && len != 26 && len != 58) { return false; } return isHex(wepKey); } private static boolean isHex(String key) { for (int i = key.length() - 1; i >= 0; i--) { final char c = key.charAt(i); if (!(c >= '0' && c <= '9' || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f')) { return false; } } return true; } static final String[] SECURITY_MODES = {WEP, WPA, WPA2, WPA_EAP, IEEE8021X}; /** * @return The security of a given {@link ScanResult}. */ public static String getScanResultSecurity(ScanResult scanResult) { final String cap = scanResult.capabilities; for (int i = SECURITY_MODES.length - 1; i >= 0; i--) { if (cap.contains(SECURITY_MODES[i])) { return SECURITY_MODES[i]; } } return OPEN; } }