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 对象并继续第四步。 说了这么多直接上代码:
此时有些小伙伴门就要问了,为什么要从列表中删除WifiConfiguration再创建新的,因为以保存列表中的WifiConfiguration并不是成功连接过的WiFi,有可能是手残输错了,若不删除直接连接将会永远也连不上的 。对于本demo因无法删除迫不得已直接连接也真的是没有办法的办法,(有哪位大神可以完美解决不妨留言给我)。当然在我项目中的解决方案是 加了一个广播接收器接收WiFi连接成功的广播,收到广播后判断已连接的WiFi名称是否与目标WiFi名称相等,若不相等,则说明列表中的WiFi名称和密码有问题(或者不在范围内),弹出toast提示用户手动将其从系统的WiFi管理器中不再保存。代码如下:
(1)wifireceiver 代码
(2)activity部分代码
本菜鸟刚入行不久,这也是我的第一篇技术博客,写的有点啰嗦,希望大家给出建议批评,哪位大神有更好的解决方案请火钳留言。鄙人感激不尽!
在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管理器中删除此网络再连接"); } } }
本菜鸟刚入行不久,这也是我的第一篇技术博客,写的有点啰嗦,希望大家给出建议批评,哪位大神有更好的解决方案请火钳留言。鄙人感激不尽!
相关文章推荐
- android请求连接wifi之后验证密码是否正确的方法
- 浅析android下如何通过jni监控wifi网络连接、dhcpcd执行和power电源控制
- Android ADB命令大全(通过ADB命令查看wifi密码、MAC地址、设备信息、操作文件、查看文件、日志信息、卸载、启动和安装APK等)
- 实现android手机通过WIFI和PC连接。
- adb通过wifi连接pc端与android设备
- Android配置----小米手机通过wifi连接ADB调试Android应用
- android通过wifi连接经常超时
- Android ADB命令大全(通过ADB命令查看wifi密码、MAC地址、设备信息、操作文件、查看文件、日志信息、卸载、启动和安装APK等)
- Android通过wifi连接Intermec PB50打印机进行条码打印
- 通过WiFi连接Android手机,进行ADB调试
- adb通过wifi连接android设备
- 浅析android下如何通过jni监控wifi网络连接、dhcpcd执行和power电源控制
- adb通过wifi连接android设备(魅族note3)
- ADB通过WIFI连接Android设备
- Android自动连接指定的wifi,免密码或指定密码
- Android ADB命令大全(通过ADB命令查看wifi密码、MAC地址、设备信息、操作文件、查看文件、日志信息、卸载、启动和安装APK等)
- WIFI 安卓Android系统手机通过USB连接电脑上网
- 浅析android下如何通过jni监控wifi网络连接、dhcpcd执行和power电源控制
- Android获取当前连接的wifi名称
- Android官方开发文档Training系列课程中文版:连接无线设备之通过WIFI创建P2P连接