我试图把编程方式添加一个WiFi网络,并连接到该网络。
我的code工作正常,如果无线网络已经打开。
如果Wi-Fi已关闭,我所看到的wifimanager.addtonetwork()失败,当我看到手机上的WiFi设置,我可以看到状态为扫描
如果我尝试重新连接工作正常。
请参见下面的code。 请帮忙
私人诠释changeNetwork(NetworkSetting设置){
//如果SSID为空,抛出一个错误和回报
如果(setting.getSsid()== NULL || setting.getSsid()长度()== 0){
返回doError(R.string.wifi_ssid_missing);
}
//如果网络类型无效
如果(setting.getNetworkType()== NetworkType.NETWORK_INVALID){
返回doError(R.string.wifi_type_incorrect);
}
//如果密码是空的,这是未加密的网络
如果(setting.getPassword()== NULL
|| setting.getPassword()长度()== 0
|| setting.getNetworkType()== NULL
|| setting.getNetworkType()== NetworkType.NETWORK_NOPASS){
返回changeNetworkUnEncrypted(设置);
}
如果(setting.getNetworkType()== NetworkType.NETWORK_WPA){
返回changeNetworkWPA(设置);
} 其他 {
返回changeNetworkWEP(设置);
}
}
私人诠释doError(INT resource_string){
statusView.setText(resource_string);
//放弃的连接
wifiManager.disconnect();
如果(networkId大于0){
wifiManager.removeNetwork(networkId);
networkId = -1;
}
如果(receiverRegistered){
unregisterReceiver(wifiReceiver);
receiverRegistered = FALSE;
}
返回-1;
}
私人WifiConfiguration changeNetworkCommon(NetworkSetting输入){
statusView.setText(R.string.wifi_creating_network);
Log.d(TAG,添加新的配置:\ nSSID:+ input.getSsid()
+\ n类型:+ input.getNetworkType());
WifiConfiguration配置=新WifiConfiguration();
config.allowedAuthAlgorithms.clear();
config.allowedGroupCiphers.clear();
config.allowedKeyManagement.clear();
config.allowedPairwiseCiphers.clear();
config.allowedProtocols.clear();
// Android的API坚持一个ASCII SSID必须加引号是正确的
//处理。
config.SSID = NetworkUtil.convertToQuotedString(input.getSsid());
config.hiddenSSID = TRUE;
返回的配置;
}
私人诠释requestNetworkChange(WifiConfiguration配置){
statusView.setText(R.string.wifi_changing_network);
返回updateNetwork(配置,FALSE);
}
//添加WEP网络
私人诠释changeNetworkWEP(NetworkSetting输入){
WifiConfiguration配置= changeNetworkCommon(输入);
字符串传递= input.getPassword();
如果(NetworkUtil.isHexWepKey(通)){
config.wepKeys [0] =通过;
} 其他 {
config.wepKeys [0] = NetworkUtil.convertToQuotedString(合格);
}
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;
返回requestNetworkChange(配置);
}
//添加WPA或WPA2网络
私人诠释changeNetworkWPA(NetworkSetting输入){
WifiConfiguration配置= changeNetworkCommon(输入);
字符串传递= input.getPassword();
//十六进制的密码是64位都没有被引用。
如果(HEX_DIGITS_64.matcher(通).matches()){
Log.d(TAG,一个64位十六进制的密码输入。);
。配置preSharedKey =通过;
} 其他 {
Log.d(TAG,一个正常的密码输入:我引用它。);
配置preSharedKey = NetworkUtil.convertToQuotedString(通)。
}
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
//对于WPA
config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
//对于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);
返回requestNetworkChange(配置);
}
//添加一个开放的,不安全的网络
私人诠释changeNetworkUnEncrypted(NetworkSetting输入){
Log.d(TAG,空口令提示,一个简单的帐户设置);
WifiConfiguration配置= changeNetworkCommon(输入);
config.wepKeys [0] =;
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
config.wepTxKeyIndex = 0;
返回requestNetworkChange(配置);
}
/ **
*如果给定的SSID名称的设置存在,然后更改其密码
*给一个在这里给定的,并保存
*
* @参数SSID
* /
私人WifiConfiguration findNetworkInExistingConfig(字符串SSID){
名单< WifiConfiguration> existingConfigs = wifiManager
.getConfiguredNetworks();
Log.i(开始比较,大小+ existingConfigs.size());
对于(WifiConfiguration existingConfig:existingConfigs){
Log.i(与SSID比较,SSID + existingConfig.SSID);
如果(existingConfig.SSID.equals(SSID)){
Log.i(比较SSID为成功,SSID + existingConfig.SSID);
返回existingConfig;
}
}
返回null;
}
@覆盖
保护无效的onCreate(包savedInstanceState){
super.onCreate(savedInstanceState);
意向意图= getIntent();
/ *如果(意向== NULL
|| !intent.getAction()。等于(Intents.WifiConnect.ACTION)){
完();
返回;
} * /
字符串SSID = intent.getStringExtra(SSID);
字符串password = intent.getStringExtra(密码);
字符串NETWORKTYPE = intent.getStringExtra(类);
的setContentView(R.layout.network);
statusView =(TextView中)findViewById(R.id.networkStatus);
NETWORKTYPE networkT;
如果(WPA.equals(NETWORKTYPE)){
networkT = NetworkType.NETWORK_WPA;
}否则如果(WEP.equals(NETWORKTYPE)){
networkT = NetworkType.NETWORK_WEP;
}否则如果(NOPASS.equals(NETWORKTYPE)){
networkT = NetworkType.NETWORK_NOPASS;
} 其他 {
networkT = NetworkType.NETWORK_INVALID;
}
//这是以前无法获得的onCreate
wifiManager =(WifiManager)this.getSystemService(WIFI_SERVICE);
//开始的WiFi,否则任何方法都行不通
wifiManager.setWifiEnabled(真正的);
//所以我们知道网络发生变化时
wifiReceiver =新WifiReceiver(wifiManager,这一点,statusView,SSID);
//订单事宜!
mWifiStateFilter =新的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;
如果(密码== NULL){
密码=;
}
Log.d(TAG,添加新的配置:\ nSSID:+ SSID +型:
+ networkT);
NetworkSetting设置=新NetworkSetting(SSID,密码,networkT);
changeNetwork(设置);
}
@覆盖
公共无效的onPause(){
super.onPause();
如果(receiverRegistered){
unregisterReceiver(wifiReceiver);
receiverRegistered = FALSE;
}
}
@覆盖
公共无效onResume(){
super.onResume();
如果(wifiReceiver = NULL和放大器;!&安培;!mWifiStateFilter = NULL
&功放;&安培; !receiverRegistered){
registerReceiver(wifiReceiver,mWifiStateFilter);
receiverRegistered = TRUE;
}
}
@覆盖
保护无效的onDestroy(){
如果(wifiReceiver!= NULL){
如果(receiverRegistered){
unregisterReceiver(wifiReceiver);
receiverRegistered = FALSE;
}
wifiReceiver = NULL;
}
super.onDestroy();
}
/ **
*更新网络:创建一个新的网络或修改现有
* 网络
*
* @参数配置
*新网络配置
* @参数disableOthers
*真实的,如果其他网络必须被禁用
*所连接的网络的@return网络ID。
* /
私人诠释updateNetwork(WifiConfiguration配置,布尔disableOthers){
WifiConfiguration发现= findNetworkInExistingConfig(config.SSID);
wifiManager.disconnect();
如果(发现== NULL){
Log.i(WIFI,SSID未找到);
statusView.setText(R.string.wifi_creating_network);
} 其他 {
statusView.setText(R.string.wifi_modifying_network);
Log.d(TAG,删除网络+ found.networkId);
wifiManager.removeNetwork(found.networkId);
wifiManager.saveConfiguration();
}
networkId = wifiManager.addNetwork(配置);
Log.d(TAG,插入/修改的网络+ networkId);
如果(networkId℃,){
wifiManager.setWifiEnabled(真正的);
networkId = wifiManager.addNetwork(配置);
Log.d(TAG,再次插入/修改的网络+ networkId);
返回FAILURE_NO_NETWORK_ID;
}
//尝试禁用当前网络,并开始一个新的。
如果(!wifiManager.enableNetwork(networkId,disableOthers)){
networkId = FAILURE_NO_NETWORK_ID;
返回FAILURE_NO_NETWORK_ID;
}
的ErrorCount = 0;
wifiManager.reassociate();
返回networkId;
}
这是我的工作code:(它不同于我的previous code)
包com.idg.project.utils;
进口的java.util.List;
进口java.util.regex.Pattern中;
进口android.net.wifi.WifiConfiguration;
进口android.net.wifi.WifiManager;
进口android.util.Log;
/ **
* @author维克拉姆AGGARWAL
* @author肖恩·欧文
* /
公共final类WifiConfigManager {
私有静态最后字符串变量= WifiConfigManager.class.getSimpleName();
私有静态最终格局HEX_DIGITS = Pattern.compile([0-9A发-F] +);
私人WifiConfigManager(){
}
公共静态无效配置(最终WifiManager wifiManager,
最后弦乐SSID,
最后的字符串密码,
最后弦乐networkTypeString){
可运行configureRunnable =新的Runnable(){
公共无效的run(){
//开始的WiFi,否则任何方法都行不通
如果(!wifiManager.isWifiEnabled()){
Log.i(TAG,启用无线网络连接。);
如果(wifiManager.setWifiEnabled(真)){
Log.i(TAG,Wi-Fi功能);
} 其他 {
Log.w(TAG,无线网络无法启用!);
返回;
}
//这个速度非常快,但需要等待它的启用。一个小忙等待?
诠释计数= 0;
而(!wifiManager.isWifiEnabled()){
如果(计数> = 10){
Log.i(TAG,时间太长启用Wi-Fi,退出);
返回;
}
Log.i(TAG,仍在等待Wi-Fi来实现......);
尝试 {
视频下载(1000L);
}赶上(InterruptedException的IE){
// 继续
}
算上++;
}
}
NETWORKTYPE NETWORKTYPE = NetworkType.forIntentValue(networkTypeString);
如果(NETWORKTYPE == NetworkType.NO_PASSWORD){
changeNetworkUnEncrypted(wifiManager,SSID);
} 其他 {
如果(密码== NULL || password.length()== 0){
抛出新抛出:IllegalArgumentException();
}
如果(NETWORKTYPE == NetworkType.WEP){
changeNetworkWEP(wifiManager,SSID,密码);
}否则,如果(NETWORKTYPE == NetworkType.WPA){
changeNetworkWPA(wifiManager,SSID,密码);
}}
}
};
新的Thread(configureRunnable)。开始();
}
/ **
*更新网络:创建一个新的网络或修改现有的网络
*参数配置新网络配置
*所连接的网络的@return网络ID。
* /
私有静态无效updateNetwork(WifiManager wifiManager,WifiConfiguration配置){
整数foundNetworkID = findNetworkInExistingConfig(wifiManager,config.SSID);
如果(foundNetworkID!= NULL){
Log.i(TAG,删除旧配置网络+ config.SSID);
wifiManager.removeNetwork(foundNetworkID);
wifiManager.saveConfiguration();
}
INT networkId = wifiManager.addNetwork(配置);
如果(networkId> = 0){
//尝试禁用当前网络,并开始一个新的。
如果(wifiManager.enableNetwork(networkId,真)){
Log.i(TAG,关联到网络+ config.SSID);
wifiManager.saveConfiguration();
} 其他 {
Log.w(TAG,无法启用网络+ config.SSID);
}
} 其他 {
Log.w(TAG,无法添加网络+ config.SSID);
}
}
私有静态WifiConfiguration changeNetworkCommon(字符串SSID){
WifiConfiguration配置=新WifiConfiguration();
config.allowedAuthAlgorithms.clear();
config.allowedGroupCiphers.clear();
config.allowedKeyManagement.clear();
config.allowedPairwiseCiphers.clear();
config.allowedProtocols.clear();
// Android的API坚持一个ASCII SSID必须用引号引起来正确处理。
config.SSID = quoteNonHex(SSID);
返回的配置;
}
//添加WEP网络
私有静态无效changeNetworkWEP(WifiManager wifiManager,SSID字符串,字符串密码){
WifiConfiguration配置= changeNetworkCommon(SSID);
config.wepKeys [0] = quoteNonHex(密码,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,配置);
}
//添加WPA或WPA2网络
私有静态无效changeNetworkWPA(WifiManager wifiManager,SSID字符串,字符串密码){
WifiConfiguration配置= changeNetworkCommon(SSID);
//十六进制的密码是64位都没有被引用。
。配置preSharedKey = quoteNonHex(密码,64);
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
config.allowedProtocols.set(WifiConfiguration.Protocol.WPA); //对于WPA
config.allowedProtocols.set(WifiConfiguration.Protocol.RSN); //对于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,配置);
}
//添加一个开放的,不安全的网络
私有静态无效changeNetworkUnEncrypted(WifiManager wifiManager,串SSID){
WifiConfiguration配置= changeNetworkCommon(SSID);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
updateNetwork(wifiManager,配置);
}
私有静态整数findNetworkInExistingConfig(WifiManager wifiManager,串SSID){
名单< WifiConfiguration> existingConfigs = wifiManager.getConfiguredNetworks();
对于(WifiConfiguration existingConfig:existingConfigs){
如果(existingConfig.SSID.equals(SSID)){
返回existingConfig.networkId;
}
}
返回null;
}
私有静态字符串quoteNonHex(字符串值,诠释...... allowedLengths){
返回isHexOfLength(值,allowedLengths)?值:convertToQuotedString(值);
}
/ **
*包围传入的字符串中的双引号,如果没有引用。
* @参数串输入字符串
返回:带引号的字符串中,格式为输入。如果输入字符串为空,则返回null
*为好。
* /
私有静态字符串convertToQuotedString(字符串字符串){
在(string == NULL || string.length减()== 0){
返回null;
}
//如果已经引用,作为回报,是
如果(string.charAt(0)==''和;&安培; string.charAt(string.length减() - 1)==){
返回的字符串;
}
回报'\'+字符串+\';
}
/ **
*参数值输入检查
* @参数allowedLengths允许的长度,如果任何
* @返回true,如果值是十六进制数字非null,非空字符串,如果允许的长度给出了
*允许的长度
* /
私有静态布尔isHexOfLength(CharSequence的价值,诠释...... allowedLengths){
如果(价值== NULL ||!HEX_DIGITS.matcher(值).matches()){
返回false;
}
如果(allowedLengths.length == 0){
返回true;
}
对于(INT长度:allowedLengths){
如果(value.length()==长度){
返回true;
}
}
返回false;
}
}
包com.idg.project.utils;
枚举NETWORKTYPE {
WEP,
WPA,
NO_PASSWORD;
静态NETWORKTYPE forIntentValue(字符串networkTypeString){
如果(networkTypeString == NULL){
返回NO_PASSWORD;
}
如果(WPA.equals(networkTypeString)){
返回WPA;
}
如果(WEP.equals(networkTypeString)){
返回WEP;
}
如果(NOPASS.equals(networkTypeString)){
返回NO_PASSWORD;
}
抛出新抛出:IllegalArgumentException(networkTypeString);
}
}
解决方案
您需要创建 wifiLock 带wifi mode_full,有点陌生的名字为这个方法,但做的工作。
I am trying to turn add a wifi network programmatically and to connect to that network.
My code works fine if the wi-fi is already turned on.
If wi-fi is off, what i see wifimanager.addtonetwork() fails and when i see the wifi settings for the phone, i can see the status as scanning
If i try to connect again it works fine.
Please see code below. Please help
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;
}
Here is my working code : ( its different from my previous code )
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, ssid, 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 ssid, 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);
}
}
解决方案
You need to create wifiLock with wifi mode_full, a bit strange name for that method but doing the work.