我试图以编程方式添加一个WiFi网络,并连接到该网络.
如果Wi-Fi已经打开,我的代码工作正常.
如果Wi-Fi关闭,我看到wifimanager.addtonetwork()失败,当我看到手机的WiFi设置,我可以看到扫描的状态
如果我尝试连接再次工作正常.
请看下面的代码.
请帮忙
private int changeNetwork(NetworkSetting setting) { // If the SSID is empty,throw an error and return if (setting.getSsid() == null || setting.getSsid().length() == 0) { return doError(R.string.wifi_ssid_missing); } // If the network type is invalid if (setting.getNetworkType() == NetworkType.NETWORK_INVALID) { return doError(R.string.wifi_type_incorrect); } // If the password is empty,this is an unencrypted network if (setting.getPassword() == null || setting.getPassword().length() == 0 || setting.getNetworkType() == null || setting.getNetworkType() == NetworkType.NETWORK_NOPASS) { return changeNetworkUnEncrypted(setting); } if (setting.getNetworkType() == NetworkType.NETWORK_WPA) { return changeNetworkWPA(setting); } else { return changeNetworkWEP(setting); } } private int doError(int resource_string) { statusView.setText(resource_string); // Give up on the connection wifiManager.disconnect(); if (networkId > 0) { wifiManager.removeNetwork(networkId); networkId = -1; } if (receiverRegistered) { unregisterReceiver(wifiReceiver); receiverRegistered = false; } return -1; } private WifiConfiguration changeNetworkCommon(NetworkSetting input) { statusView.setText(R.string.wifi_creating_network); Log.d(TAG,"Adding new configuration: \nSSID: " + input.getSsid() + "\nType: " + input.getNetworkType()); WifiConfiguration config = new WifiConfiguration(); config.allowedAuthAlgorithms.clear(); config.allowedGroupCiphers.clear(); config.allowedKeyManagement.clear(); config.allowedPairwiseCiphers.clear(); config.allowedProtocols.clear(); // Android API insists that an ascii SSID must be quoted to be correctly // handled. config.SSID = NetworkUtil.convertToQuotedString(input.getSsid()); config.hiddenSSID = true; return config; } private int requestNetworkChange(WifiConfiguration config) { statusView.setText(R.string.wifi_changing_network); return updateNetwork(config,false); } // Adding a WEP network private int changeNetworkWEP(NetworkSetting input) { WifiConfiguration config = changeNetworkCommon(input); String pass = input.getPassword(); if (NetworkUtil.isHexWepKey(pass)) { config.wepKeys[0] = pass; } else { config.wepKeys[0] = NetworkUtil.convertToQuotedString(pass); } config.allowedAuthAlgorithms .set(WifiConfiguration.AuthAlgorithm.SHARED); config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP); config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40); config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104); config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); config.wepTxKeyIndex = 0; return requestNetworkChange(config); } // Adding a WPA or WPA2 network private int changeNetworkWPA(NetworkSetting input) { WifiConfiguration config = changeNetworkCommon(input); String pass = input.getPassword(); // Hex passwords that are 64 bits long are not to be quoted. if (HEX_DIGITS_64.matcher(pass).matches()) { Log.d(TAG,"A 64 bit hex password entered."); config.preSharedKey = pass; } else { Log.d(TAG,"A normal password entered: I am quoting it."); config.preSharedKey = NetworkUtil.convertToQuotedString(pass); } config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN); // For WPA config.allowedProtocols.set(WifiConfiguration.Protocol.WPA); // For WPA2 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP); config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); config.allowedProtocols.set(WifiConfiguration.Protocol.RSN); return requestNetworkChange(config); } // Adding an open,unsecured network private int changeNetworkUnEncrypted(NetworkSetting input) { Log.d(TAG,"Empty password prompting a simple account setting"); WifiConfiguration config = changeNetworkCommon(input); config.wepKeys[0] = ""; config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); config.wepTxKeyIndex = 0; return requestNetworkChange(config); } /** * If the given ssid name exists in the settings,then change its password * to the one given here,and save * * @param ssid */ private WifiConfiguration findNetworkInExistingConfig(String ssid) { List<WifiConfiguration> existingConfigs = wifiManager .getConfiguredNetworks(); Log.i("Start comparing","Size "+existingConfigs.size() ); for (WifiConfiguration existingConfig : existingConfigs) { Log.i("Compare with SSID",ssid + existingConfig.SSID); if (existingConfig.SSID.equals(ssid)) { Log.i("Compare success with SSID",ssid + existingConfig.SSID); return existingConfig; } } return null; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent intent = getIntent(); /* if (intent == null || !intent.getAction().equals(Intents.WifiConnect.ACTION)) { finish(); return; } */ String ssid = intent.getStringExtra("ssid"); String password = intent.getStringExtra("password"); String networkType = intent.getStringExtra("type"); setContentView(R.layout.network); statusView = (TextView) findViewById(R.id.networkStatus); NetworkType networkT; if ("WPA".equals(networkType)) { networkT = NetworkType.NETWORK_WPA; } else if ("WEP".equals(networkType)) { networkT = NetworkType.NETWORK_WEP; } else if ("nopass".equals(networkType)) { networkT = NetworkType.NETWORK_NOPASS; } else { networkT = NetworkType.NETWORK_INVALID; } // This is not available before onCreate wifiManager = (WifiManager) this.getSystemService(WIFI_SERVICE); // Start WiFi,otherwise nothing will work wifiManager.setWifiEnabled(true); // So we know when the network changes wifiReceiver = new WifiReceiver(wifiManager,this,statusView,ssid); // The order matters! mWifiStateFilter = new IntentFilter( WifiManager.WIFI_STATE_CHANGED_ACTION); mWifiStateFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); mWifiStateFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); mWifiStateFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); registerReceiver(wifiReceiver,mWifiStateFilter); receiverRegistered = true; if (password == null) { password = ""; } Log.d(TAG,"Adding new configuration: \nSSID: " + ssid + "Type: " + networkT); NetworkSetting setting = new NetworkSetting(ssid,password,networkT); changeNetwork(setting); } @Override public void onPause() { super.onPause(); if (receiverRegistered) { unregisterReceiver(wifiReceiver); receiverRegistered = false; } } @Override public void onResume() { super.onResume(); if (wifiReceiver != null && mWifiStateFilter != null && !receiverRegistered) { registerReceiver(wifiReceiver,mWifiStateFilter); receiverRegistered = true; } } @Override protected void onDestroy() { if (wifiReceiver != null) { if (receiverRegistered) { unregisterReceiver(wifiReceiver); receiverRegistered = false; } wifiReceiver = null; } super.onDestroy(); } /** * Update the network: either create a new network or modify an existing * network * * @param config * the new network configuration * @param disableOthers * true if other networks must be disabled * @return network ID of the connected network. */ private int updateNetwork(WifiConfiguration config,boolean disableOthers) { WifiConfiguration found = findNetworkInExistingConfig(config.SSID); wifiManager.disconnect(); if (found == null) { Log.i("WIFI","SSID NOT FOUND"); statusView.setText(R.string.wifi_creating_network); } else { statusView.setText(R.string.wifi_modifying_network); Log.d(TAG,"Removing network " + found.networkId); wifiManager.removeNetwork(found.networkId); wifiManager.saveConfiguration(); } networkId = wifiManager.addNetwork(config); Log.d(TAG,"Inserted/Modified network " + networkId); if (networkId < 0) { wifiManager.setWifiEnabled(true); networkId = wifiManager.addNetwork(config); Log.d(TAG,"Again Inserted/Modified network " + networkId); return FAILURE_NO_NETWORK_ID; } // Try to disable the current network and start a new one. if (!wifiManager.enableNetwork(networkId,disableOthers)) { networkId = FAILURE_NO_NETWORK_ID; return FAILURE_NO_NETWORK_ID; } errorCount = 0; wifiManager.reassociate(); return networkId; }
package com.idg.project.utils; import java.util.List; import java.util.regex.Pattern; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.util.Log; /** * @author Vikram Aggarwal * @author Sean Owen */ public final class WifiConfigManager { private static final String TAG = WifiConfigManager.class.getSimpleName(); private static final Pattern HEX_DIGITS = Pattern.compile("[0-9A-Fa-f]+"); private WifiConfigManager() { } public static void configure(final WifiManager wifiManager,final String ssid,final String password,final String networkTypeString) { Runnable configureRunnable = new Runnable() { public void run() { // Start WiFi,otherwise nothing will work if (!wifiManager.isWifiEnabled()) { Log.i(TAG,"Enabling wi-fi..."); if (wifiManager.setWifiEnabled(true)) { Log.i(TAG,"Wi-fi enabled"); } else { Log.w(TAG,"Wi-fi could not be enabled!"); return; } // This happens very quickly,but need to wait for it to enable. A little busy wait? int count = 0; while (!wifiManager.isWifiEnabled()) { if (count >= 10) { Log.i(TAG,"Took too long to enable wi-fi,quitting"); return; } Log.i(TAG,"Still waiting for wi-fi to enable..."); try { Thread.sleep(1000L); } catch (InterruptedException ie) { // continue } count++; } } NetworkType networkType = NetworkType.forIntentValue(networkTypeString); if (networkType == NetworkType.NO_PASSWORD) { changeNetworkUnEncrypted(wifiManager,ssid); } else { if (password == null || password.length() == 0) { throw new IllegalArgumentException(); } if (networkType == NetworkType.WEP) { changeNetworkWEP(wifiManager,ssid,password); } else if (networkType == NetworkType.WPA) { changeNetworkWPA(wifiManager,password); } } } }; new Thread(configureRunnable).start(); } /** * Update the network: either create a new network or modify an existing network * @param config the new network configuration * @return network ID of the connected network. */ private static void updateNetwork(WifiManager wifiManager,WifiConfiguration config) { Integer foundNetworkID = findNetworkInExistingConfig(wifiManager,config.SSID); if (foundNetworkID != null) { Log.i(TAG,"Removing old configuration for network " + config.SSID); wifiManager.removeNetwork(foundNetworkID); wifiManager.saveConfiguration(); } int networkId = wifiManager.addNetwork(config); if (networkId >= 0) { // Try to disable the current network and start a new one. if (wifiManager.enableNetwork(networkId,true)) { Log.i(TAG,"Associating to network " + config.SSID); wifiManager.saveConfiguration(); } else { Log.w(TAG,"Failed to enable network " + config.SSID); } } else { Log.w(TAG,"Unable to add network " + config.SSID); } } private static WifiConfiguration changeNetworkCommon(String ssid) { WifiConfiguration config = new WifiConfiguration(); config.allowedAuthAlgorithms.clear(); config.allowedGroupCiphers.clear(); config.allowedKeyManagement.clear(); config.allowedPairwiseCiphers.clear(); config.allowedProtocols.clear(); // Android API insists that an ascii SSID must be quoted to be correctly handled. config.SSID = quoteNonHex(ssid); return config; } // Adding a WEP network private static void changeNetworkWEP(WifiManager wifiManager,String ssid,String password) { WifiConfiguration config = changeNetworkCommon(ssid); config.wepKeys[0] = quoteNonHex(password,10,26,58); config.wepTxKeyIndex = 0; config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED); config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP); config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40); config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104); updateNetwork(wifiManager,config); } // Adding a WPA or WPA2 network private static void changeNetworkWPA(WifiManager wifiManager,String password) { WifiConfiguration config = changeNetworkCommon(ssid); // Hex passwords that are 64 bits long are not to be quoted. config.preSharedKey = quoteNonHex(password,64); config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN); config.allowedProtocols.set(WifiConfiguration.Protocol.WPA); // For WPA config.allowedProtocols.set(WifiConfiguration.Protocol.RSN); // For WPA2 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP); config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP); config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP); config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP); config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); updateNetwork(wifiManager,config); } // Adding an open,unsecured network private static void changeNetworkUnEncrypted(WifiManager wifiManager,String ssid) { WifiConfiguration config = changeNetworkCommon(ssid); config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); updateNetwork(wifiManager,config); } private static Integer findNetworkInExistingConfig(WifiManager wifiManager,String ssid) { List<WifiConfiguration> existingConfigs = wifiManager.getConfiguredNetworks(); for (WifiConfiguration existingConfig : existingConfigs) { if (existingConfig.SSID.equals(ssid)) { return existingConfig.networkId; } } return null; } private static String quoteNonHex(String value,int... allowedLengths) { return isHexOfLength(value,allowedLengths) ? value : convertToQuotedString(value); } /** * Encloses the incoming string inside double quotes,if it isn't already quoted. * @param string the input string * @return a quoted string,of the form "input". If the input string is null,it returns null * as well. */ private static String convertToQuotedString(String string) { if (string == null || string.length() == 0) { return null; } // If already quoted,return as-is if (string.charAt(0) == '"' && string.charAt(string.length() - 1) == '"') { return string; } return '\"' + string + '\"'; } /** * @param value input to check * @param allowedLengths allowed lengths,if any * @return true if value is a non-null,non-empty string of hex digits,and if allowed lengths are given,has * an allowed length */ private static boolean isHexOfLength(CharSequence value,int... allowedLengths) { if (value == null || !HEX_DIGITS.matcher(value).matches()) { return false; } if (allowedLengths.length == 0) { return true; } for (int length : allowedLengths) { if (value.length() == length) { return true; } } return false; } } package com.idg.project.utils; enum NetworkType { WEP,WPA,NO_PASSWORD; static NetworkType forIntentValue(String networkTypeString) { if (networkTypeString == null) { return NO_PASSWORD; } if ("WPA".equals(networkTypeString)) { return WPA; } if ("WEP".equals(networkTypeString)) { return WEP; } if ("nopass".equals(networkTypeString)) { return NO_PASSWORD; } throw new IllegalArgumentException(networkTypeString); } }