您的位置:首页 > 移动开发 > Android开发

Android6.0通过WiFi名称密码连接WiFi的方案

2017-12-11 23:52 696 查看
最近项目中有通过已知WiFi名称和密码连接传感器WiFi,实现数据交换的需求。开始在网上找了点资料很快搞定,简单测试了一下也能连,得意洋洋了一会再测就发现了问题。继续研究发现是6.0以后WiFi相关sdk变化所致。现在就一步一步记录我的WiFi心路历程:

在6.0以前的版本中连接WiFi分三大步,也就是我最开始的方法:1、打开WiFi(若打开则不用管);2、判断要连接的WiFi是否已经保存在你手机的WiFi列表中(之前是否连接过,可以在手机已保存的列表中查看)3、若列表中存在此WiFi,则将其从列表删除并重新创建WifiConfiguration 对象;4、添加到网络并连接。

而我经过反复断点发现问题出在第3步,原来在6.0以后,将不会保证你能正常删除已存在的WifiConfiguration 对象,删除的前提是列表中的对象时通过你自己的APP创建的。比如,你通过系统的WiFi管理器保存了名为 “myWifi”的一个列表项,那么你在自己的项目中将无法从已有列表删除。 我的解决方案是在删除之前之后分别获取一次列表,比较两次获取的列表的数目是否相等,若相等则直接连接,若不相等说明删除成功接着创建新的WifiConfiguration 对象并继续第四步。 说了这么多直接上代码:

public class WifiUtil {
//密码类型
public static final int TYPE_NO_PWD = 1;
public static final int TYPE_WEB = 2;
public static final int TYPE_WPA = 3;
// 定义WifiManager对象
private WifiManager mWifiManager;
// 网络连接列表
private List<WifiConfiguration> mWifiConfiguration;

// 构造器
public WifiUtil(Context context) {
// 取得WifiManager对象
mWifiManager = (Wif
b24b
iManager) context
.getSystemService(Context.WIFI_SERVICE);
}

// 打开WIFI
public void openWifi(Context context) {
if (!mWifiManager.isWifiEnabled()) {
mWifiManager.setWifiEnabled(true);
}
}

// 得到接入点的BSSID
public String getBSSID() {
return (mWifiInfo == null) ? "NULL" : mWifiInfo.getBSSID();
}

// 得到接入点的SSID
public String getSSID() {
return (mWifiInfo == null) ? "NULL" : mWifiInfo.getSSID();
}

// 得到连接的ID
public int getNetworkId() {
return (mWifiInfo == null) ? 0 : mWifiInfo.getNetworkId();
}

// 添加一个网络并连接
public void addNetwork(WifiConfiguration wcg) {
int wcgID = mWifiManager.addNetwork(wcg);
boolean b =  mWifiManager.enableNetwork(wcgID, true);
}

// 断开指定ID的网络
public void disconnectWifi(int netId) {
mWifiManager.disableNetwork(netId);
mWifiManager.disconnect();
}
public void removeWifi(int netId) {
disconnectWifi(netId);
mWifiManager.removeNetwork(netId);
}
//创建WifiConfiguration对象
public WifiConfiguration CreateWifiInfo(String SSID, String Password, int Type) {
WifiConfiguration config = new WifiConfiguration();
config.allowedAuthAlgorithms.clear();
config.allowedGroupCiphers.clear();
config.allowedKeyManagement.clear();
config.allowedPairwiseCiphers.clear();
config.allowedProtocols.clear();
config.SSID = "\"" + SSID + "\"";

WifiConfiguration tempConfig = this.IsExsits(SSID);
List<WifiConfiguration> beforConfiguration = mWifiManager.getConfiguredNetworks();
if(tempConfig != null) {
mWifiManager.removeNetwork(tempConfig.networkId);
}
List<WifiConfiguration> afterConfiguration = mWifiManager.getConfiguredNetworks();

if(beforConfiguration.size()==afterConfiguration.size()){ //若相等则说明没有删除,列表中已存在,直接连接即可
addNetwork(tempConfig);
return null;
}else {     //删除成功后根据密码的类型 进行创建新的 WifiConfiguration,  无密码, web ,wpa
if(Type == TYPE_NO_PWD) {   //WIFICIPHER_NOPASS
config.wepKeys[0] = "";
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
config.wepTxKeyIndex = 0;
}
if(Type == TYPE_WEB)  {
config.hiddenSSID = true;
config.wepKeys[0]= "\""+Password+"\"";
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;
}
if(Type == TYPE_WPA) {  //WIFICIPHER_WPA
config.preSharedKey = "\""+Password+"\"";
config.hiddenSSID = true;
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
//config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
config.status = WifiConfiguration.Status.ENABLED;
}
return config;
}

}

//判断以保存列表中是否有当前ssid的WiFi
private WifiConfiguration IsExsits(String SSID) {
List<WifiConfiguration> existingConfigs = mWifiManager.getConfiguredNetworks();
if(existingConfigs!=null && existingConfigs.size()>0){
for (WifiConfiguration existingConfig : existingConfigs) {
if (existingConfig.SSID.equals("\""+SSID+"\"")) {
return existingConfig;
}
}
}
return null;
}
}


此时有些小伙伴门就要问了,为什么要从列表中删除WifiConfiguration再创建新的,因为以保存列表中的WifiConfiguration并不是成功连接过的WiFi,有可能是手残输错了,若不删除直接连接将会永远也连不上的 。对于本demo因无法删除迫不得已直接连接也真的是没有办法的办法,(有哪位大神可以完美解决不妨留言给我)。当然在我项目中的解决方案是 加了一个广播接收器接收WiFi连接成功的广播,收到广播后判断已连接的WiFi名称是否与目标WiFi名称相等,若不相等,则说明列表中的WiFi名称和密码有问题(或者不在范围内),弹出toast提示用户手动将其从系统的WiFi管理器中不再保存。代码如下:

(1)wifireceiver 代码

public class WifiReceiver extends BroadcastReceiver {
private onWifiConnectListner mListner;
public WifiReceiver() {

}
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equals( WifiManager.NETWORK_STATE_CHANGED_ACTION)){
NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
if(info.getState().equals(NetworkInfo.State.CONNECTED)){
WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
String ssid = wifiInfo.getSSID();  //连接到的网络的ssid
mListner.isConnectMyWifi(ssid);
}
}
}

public interface onWifiConnectListner{
public void isConnectMyWifi(String ssid);
}
public void setOnWifiConnetListner(onWifiConnectListner listner){
this.mListner = listner;
}
}


(2)activity部分代码

//注册广播,并给广播设置监听器(此activity需实现WifiReceiver.onWifiConnectListner接口)

wifiReceiver = new WifiReceiver();
wifiReceiver.setOnWifiConnetListner(this);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
registerReceiver(wifiReceiver, intentFilter);

//实现监听的方法
@Override
public void isConnectMyWifi(String s) {

if (!TextUtils.isEmpty(ssid)) {
if (!s.equals("\"" + ssid + "\"")) {  //连接到指定网络 获取信息
} else {    //未连接到指定网络
showShortToast("连接失败,请在系统WiFi管理器中删除此网络再连接");
}
}
}


本菜鸟刚入行不久,这也是我的第一篇技术博客,写的有点啰嗦,希望大家给出建议批评,哪位大神有更好的解决方案请火钳留言。鄙人感激不尽!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐