记录:WiFi的链接
来源:互联网 发布:数控镗铣床编程代码 编辑:程序博客网 时间:2024/06/06 07:20
摘要:最近遇到需要自己把WiFi的界面重新定义一下。并进行可以连接。在这里进行记录一下,方便后面的查找
对应WiFi的使用的想到的肯定是WifiManager,因为各种各样的 Manager提供简单方便的使用,在看见WifiManager的看是就基本上说明由那些作用。
It deals with several categories of items:
- The list of configured networks. The list can be viewed and updated,
and attributes of individual entries can be modified. - The currently active Wi-Fi network, if any. Connectivity can be
established or torn down, and dynamic information about the state of
the network can be queried. - Results of access point scans, containing enough information to
make decisions about what access point to connect to. - It defines the names of various Intent actions that are broadcast upon any sort of change in Wi-Fi state.
在类的开始有一句话很重要
`it should only be obtained from an application context, and not from any other derived context to avoid memory leaks within the calling process.
hah,我也是通过必应翻译的,意思是我们要用 context.getApplicationContext(),而不是其子类,因为这样可能造成内存溢出。在后面的版本(N)中,这个问题系统自身就解决了。在实例化好WifiManager对象后,调用startScan( )方法就开始进行扫描,再调用getScanResults( )。就会返回搜索到的WiFi信息,返回一个List 。ScanResult类中,我用到的只有 SSID(热点的名称),capabilities(包含了密码为何种的加密方式),level(信号的强度)。
这样就好了。答案却不是。在通过 WifiManager.isWifiEnabled()的方法判断wifi是否打开之后,用WifiManager.setWifiEnabled(true)或false,去开关wifi。关闭wifi重新打开之后返回的扫描结果长度为 0。为此不得不提到 WifiManager中的几个广播了。在这些广播中可以返回各种数据,有的广播可以返回几个数据,通过不key去获取。
WifiManager中几个用到的广播广播(action)作用获取返回值的key返回值WIFI_STATE_CHANGED_ACTION = “android.net.wifi.WIFI_STATE_CHANGED”指示已启用 wi-fi、禁用、启用、禁用或未知。- EXTRA_WIFI_STATE
- EXTRA_PREVIOUS_WIFI_STATE
- getIntExtra(String,int),共五种状态
- 返回前一个wifi状态,不知道什么意思,没有测试过。不知道是不是像相机一个的前后,因为上面它写了这个要支持才行
- EXTRA_NETWORK_INFO
- EXTRA_BSSID
- EXTRA_WIFI_INFO
- getParcelableExtra(String),返回一个NetworkInfo
- getStringExtra(String), 一个字符串的查找键, 给出了我们所连接的接入点的 BSSID。仅在新状态连接时出现。
- getParcelableExtra(String),返回一个WifiInfo。对象的查找键, 提供有关连接的访问点的信息。仅在新状态连接时出现。
- EXTRA_NEW_STATE
- EXTRA_SUPPLICANT_ERROR
- getParcelableExtra(String),描述新状态的 SupplicantState
- getIntExtra(String, int), SupplicantState 的查找键, 描述请求程序错误代码 (如果有)
可以通过WIFI_STATE_CHANGED_ACTION广播去获取当前wifi的状态,在状态为 WIFI_STATE_ENABLE情况下使用startScan( )方式,开启搜索。在SCAN_RESULTS_AVAILABLE_ACTION广播中去获取这个搜索的结果。使用NETWORK_STATE_CHANGED_ACTION去获取到这个wifi连接的一状态。其中wifi状态由五种分别是:WIFI_STATE_DISABLED ,WIFI_STATE_DISABLING ,WIFI_STATE_ENABLED ,WIFI_STATE_ENABLING ,WIFI_STATE_UNKNOWN。而NetworkInfo的状态通过getState()去得到NetworkInfo.State 。NetworkInfo.State.DISCONNECTED表示连接已断开。NetworkInfo.State.CONNECTED表示连接完成。通过wifiManager.getConnectionInfo()获得WifiInfo,再通过getSSID( )获取到对应的热点名称。其中,NetworkInfo.State还有几种其它状态。还可有更加具体状态信息,通过 NetworkInfo.DetailedState stateD = info.getDetailedState(),去获取,其中有很多状态,如:IDLE(空闲),SCANNING(正在扫描),CONNECTING(连接中),AUTHENTICATING(正在验证身份信息),OBTAINING_IPADDR(正在获取IP地址),CONNECTING(连接中),CONNECTED(已连接),等等,等等。一系列。而且后面的还在增加。如:VERIFYING_POOR_LINK(暂时关闭(网络状况不佳))需要API16,CAPTIVE_PORTAL_CHECK(判断是否需要浏览器二次登录)API17。
以下是我关闭wifi和打开wifi,以上几个广播打印的 Log
//关闭wifiI/WifiAdminUtil ->: BroadCastReceiver NETWORK_STATE_CHANGED_ACTION I/WifiAdminUtil ->: BroadCastReceiver NETWORK_STATE_CHANGED_ACTION I/WifiAdminUtil ->: BroadCastReceiver WIFI_STATE_CHANGED_ACTION extra = 3I/WifiAdminUtil ->: BroadCastReceiver SUPPLICANT_STATE_CHANGED_ACTION err = 0I/WifiAdminUtil ->: BroadCastReceiver SUPPLICANT_CONNECTION_CHANGE_ACTION extra = falseI/WifiAdminUtil ->: BroadCastReceiver WIFI_STATE_CHANGED_ACTION extra = 0//开启wifiI/WifiAdminUtil ->: start scan millis1503825827873I/WifiAdminUtil ->: BroadCastReceiver WIFI_STATE_CHANGED_ACTION extra = 1I/WifiAdminUtil ->: BroadCastReceiver WIFI_STATE_CHANGED_ACTION extra = 2I/WifiAdminUtil ->: BroadCastReceiver SUPPLICANT_CONNECTION_CHANGE_ACTION extra = trueI/WifiAdminUtil ->: BroadCastReceiver SUPPLICANT_STATE_CHANGED_ACTION err = 0I/WifiAdminUtil ->: BroadCastReceiver SCAN_RESULTS_AVAILABLE_ACTIONI/WifiAdminUtil ->: BroadCastReceiver SUPPLICANT_STATE_CHANGED_ACTION err = 0I/WifiAdminUtil ->: BroadCastReceiver SUPPLICANT_STATE_CHANGED_ACTION err = 0I/WifiAdminUtil ->: BroadCastReceiver SUPPLICANT_STATE_CHANGED_ACTION err = 0I/WifiAdminUtil ->: BroadCastReceiver NETWORK_STATE_CHANGED_ACTIONI/WifiAdminUtil ->: BroadCastReceiver SUPPLICANT_STATE_CHANGED_ACTION err = 0I/WifiAdminUtil ->: BroadCastReceiver RSSI_CHANGED_ACTION extra = -38I/WifiAdminUtil ->: BroadCastReceiver SUPPLICANT_STATE_CHANGED_ACTION I/WifiAdminUtil ->: BroadCastReceiver RSSI_CHANGED_ACTION extra = -38I/WifiAdminUtil ->: BroadCastReceiver NETWORK_STATE_CHANGED_ACTIONI/WifiAdminUtil ->: BroadCastReceiver NETWORK_STATE_CHANGED_ACTIONI/WifiAdminUtil ->: BroadCastReceiver NETWORK_STATE_CHANGED_ACTION
从以上获取搜索的结果后,我们就可以进行连接。在连接之前先查看一下断开的连接的操作。不破不立吗,没有断开之前的连接。也就不能有新的连接了。断开通过mWifiManager.disconnect()
就可以断开了。在手机还有一个忘记密码的操作,其忘记连接密码可以通过如下就实现:
- mWifiManager.getConnectionInfo()获取当前连接的WifiInfo
- mWifiInfo.getNetworkId()通过此方法获取网络的ID
- mWifiManager.disableNetwork(netId),关闭断当前的网络
- mWifiManager.disconnect()与当前活动的接入点解除关联
’好了,接下我们就可以通过WiFi的名称和密码。完成WiFi的连接。连接的主要就是通过搜索到的wifi名称,和该wifi的密码加密类型。加上输入的密码。怎么创建成一个符合要求的类对象(WifiConfiguration)。先说说密码的加密类型,如下:
/** * 判断扫描的的热点的加密方式,通过 capabilities字段 * * @param scanResult * @return */ public String encryptionMetho(ScanResult scanResult) { //在demo和我自己在WifiConfiguration KeyMgmt 中看见的不一样 /** * 在自己的测试中,如果没有密码的公共热点。capabilities = [ESS],其余都有各种加密方式在前面 * * 其中源于百度的引用 https://zhidao.baidu.com/question/197383906.html * 密码的方式共有 3种,WEP , WPA , WPA2 * WEP 的密码架构有缺陷,很容易让无线黑客攻击,不建议使用 * WPA , WAP2 都是很强壮的密码,目前的破解难度很大(当然,原密码不能过于的简单) * 至于 AES , TKIP , TKIP&AES 这些都是 wap的加密算法 */ String desc = ""; String descOri = scanResult.capabilities; if (!descOri.equals("")|| !TextUtils.isEmpty(descOri)|| descOri != null) { if (descOri.toUpperCase().contains("WPA-PSK")) { desc = "WPA"; } else if (descOri.toUpperCase().contains("WPA2-PSK")) { desc = "WPA2"; } else if (descOri.toUpperCase().contains("WPA-PSK") && descOri.toUpperCase().contains("WPA2-PSK")) { desc = "WPA/WPA2"; } else if (descOri.toUpperCase().contains("WEP")) { //很少使用 desc = "WEP"; } else { desc = ""; } } return desc ; }
以上自是自己写的一个,写在上面只是想知道这个对不对。其中的创建对象的方法是直接从网络上拷贝的一个,看来一下基本上博客的创建方式是一样的。自己也是抄抄,测试一下可以使用。由于现在的加密方式基本是WPA ,WPA2。没有找到WEP。搜索到热点的 capabilities的字段内容为“[WPA-PSK-CCMP+TKIP][WPA2-PSK-CCMP+TKIP][ESS]“ ,估计其中创建判断PSK估计就是指WPA|WPA2的加密方式吧!其中WifiConfiguration中的几个变量的意思先介绍一下
其创建一个WifiConfiguration对象如下:
/** * 创建一个 WifiConfiguration,其参数配置看 connect里面的注释 * * @return */ private WifiConfiguration createWifiInfo(String ssid, String psk, 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 = isExsits(ssid); if (tempConfig != null) { //以前配置过,就移除以前的 mWifiManager.removeNetwork(tempConfig.networkId); } //三种加密方式,没有密码,wpa,wep if (type == TYPE_NO_PASSWD) {// config.wepKeys[0] = "";// config.wepTxKeyIndex = 0; //有的博客为以上两句编写的话,不可以连接上没有密码的热点(在模拟器测试是这样的,真机未测) config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); } else if (type == TYPE_WEP) { config.preSharedKey = "\"" + psk + "\""; config.hiddenSSID = true; 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; } else if (type == TYPE_WPA) { //修改之后的配置 config.preSharedKey = "\"" + psk + "\""; config.hiddenSSID = true; config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN); config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP); config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP); config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP); config.status = WifiConfiguration.Status.ENABLED; } else { return null; } Log.i(TAG,"createWifiInfo "+"ssid = "+ssid+" , psk = "+psk+" ,type = "+type) ; return config; }
其中注意在没有密码的创建要把注释的两局注释掉,不然真的不能成功。上面里面还有两个方法用于判断之前是否配置过,和删除配置(系统方法)。其代码如下: /** * 循环遍历查出以前是否调加过该网络 * * @param ssid 热点名称 * @return 如果添加过,则返回以前的配置 */ private WifiConfiguration isExsits(String ssid) { List<WifiConfiguration> networks = mWifiManager.getConfiguredNetworks(); for (WifiConfiguration network : networks) { if (network.SSID.equals("\"" + ssid + "\"")) { return network; } } return null; }
上面就准备好了一切,就可以开始连接了。步骤如下:
- mWifiManager.addNetwork(wifiConfig) ,添加一个新的网络描述为一组配置的网络。
- mWifiManager.disconnect() ,断开连接
- mWifiManager.enableNetwork(netId, true) ,设置为true,尝试其他的连接断开
- mWifiManager.reconnect()
通过以上几个步级完成连接,在这里面我并没有调用“mWifiManager.saveConfiguration()“ 在连接只有,WiFi热点也被记录了下来。看里面没有写默认会被保存,可能是测试机的原因吧。
代码连接:http://download.csdn.net/download/guyuelin123/9952893
参考链接
- Android Wifi模块 ScanResult类源码分析
- Android之WifiManager
- Android wifi的WifiInfo对象详解
- Android WiFi开发教程(二)——WiFi的搜索和连接
- Android应用程序创建热点以及自动链接Wifi,我遇到的问题以及我是怎么解决的
- Android连接指定Wifi的方法
- Android WIFI 分析(一)
- 记录:WiFi的链接
- android wifi 的链接
- 链接到指定的wifi
- wifi链接
- 链接的记录
- 记录有用的链接
- 检查wifi或3g的链接
- win8删除链接过的WiFi信息
- wifi记录
- 移植usb-wifi出现的问题记录
- WIFI模块--ESP8266的学习记录
- 记录优秀的网址链接
- 一些教程链接的记录
- caffe的相关链接记录
- 记录自己有用的链接
- linux wifi 链接问题
- wifi 链接流程
- 360WiFi链接问题
- C++实现单例模式
- jstl 遇到的那些坑。很有名的坑,但容易忘。记录一下,便于复习
- SQLserver本地数据库开发
- Openresty 动态2017.8
- Mysql中LAST_INSERT_ID()的函数使用详解
- 记录:WiFi的链接
- Hibernate10_映射关系---OneToOne单向
- 继续完成1万小时理论,就是成就感
- 并发编程设计模式--Immutable Object
- Ubuntu搭建dhcpv4+dhcpv6服务器(Kea DHCP Server V1.2.0)
- java零基础篇:(一)计算机基础介绍和功能键的认识
- 机器学习之SVM
- 正则表达式-特殊字符
- 去除dialog小黑点