记录一次Android端获取WiFi列表,并实现连接的过程。
需求:
获取WiFi列表,并连接无密码的指定wifi。wifi状态连接成功之后调取第三方接口进行验证,接口请求类型GET。
牢骚:没做锅啊,小白一个。怎么办?,群里闲聊两小时,不如百度一分钟。(实际好多分钟。。。)
调查与研究:
、、、、网上关于获取wifi列表,并连接wifi的文章也有很多,每一篇都点来看看。会发现,哇,蛮有趣的,一如研究深似海,发现了各种问题,把每一条都记下来,也许会遇到。万一遇到了呢,多一个else也许死的不是太惨。
一、权限问题。
Android系统版本有那么好几个,目前太低了也估计没人再用了。最常见的从 android 6.0 开始,7.0,8.0,9.0.
区别大多都是在各个版本里的权限有所改变,比如说在网上看到的,在6.0里需要定位权限等,小白哪有时间去考虑那么多,那边催的紧啊,一股脑的把权限都加上!没有就去申请。
//定位权限,获取app内常用权限
String[] permsLocation = {"android.permission.ACCESS_WIFI_STATE"
, "android.permission.CHANGE_WIFI_STATE"
, "android.permission.ACCESS_COARSE_LOCATION"
, "android.permission.ACCESS_FINE_LOCATION"};
注意:并非所有基于Android的设备都提供Wi-Fi功能。如果您的应用程序使用Wi-Fi,请 在清单文件中用元素声明 uses-feature android:name=“android.hardware.wifi”
基本需要的权限 都给它加上。联网啊,定位啊,加上再说。具体细节暂不在研究细说。
等等,除了权限加上了。更恶心的是,Android手机版本太多,网上还说如小米手机,获取不到WiFi列表的原因,竟然是
小米手机的启用MIUI优化这个设置。
如果你关闭了这个设置可能就会获取不到wifi列表 (来源其他文章,我用的华为测试机)
无论怎么说,在安全这块,android系统版本越高,以后的权限限制会更加严格。隔壁ios小姐姐还在烦恼wifi权限问题还要需要向苹果写邮件申请呢。(嘤嘤嘤)
在anroid各个版本中关于wifi的相关类方法也有所改变。权限不够的极端办法
在 AndroidManifest.xml 中加入 android:sharedUserId=“android.uid.system”,并且使用系统签名后,你懂的
其各种动态申请权限的过程就飞锅。。。
二,基本知识
1.所用到的基本类
WifiManager :此类用于管理wifi连接所有方面的API。管理类.
ScanResult : 描述有关检测到的接入点信息。扫描返回信息类型。
wifiConfiguration :wifi一些网络配置信息(安全协议、密钥管理方案,组管理密码等)在API29中已弃用。
WifiInfo: 当前连接的wifi热点信息 。
2.关键词
SSID: wifi名称。
BSSID:wifi的 mac地址。(实际情况有所出入)
networkID : 数字型的id.
nettworkInfo :获取网络信息(如连接wifi)
RSSI :wifi信号强弱的值。。也叫level.等级
3,加密方式
没加密:连接的时候,只需要SSID,不需要密码。
WEP加密:连接的时候,需要SSID和password. 设置密码:config.wepKeys[0]
WPA/WPA2加密:连接的时候,需要SSID和password. 设置密码:config.preSharedKey
802.1 x EAP加密:需设置相关参数 。
具体加密方式的详细信息,可单独进行找度娘。
4,wifi状态枚举
WIFI_STATE_DISABLING wifi正在关闭
WIFI_STATE_DISABLED wifi关闭
WIFI_STATE_ENABLING wifi正在开启
WIFI_STATE_ENABLED wifi开启
WIFI_STATE_UNKNOW wifi未知
值依次为0~4
5,wifi状态改变的相关广播事件
WifiManager.WIFI_STATE_CHANGED_ACTION wifi开关变化通知
WifiManager.SCAN_RESULTS_AVAILABLE_ACTION wifi扫描结果通知
WifiManager.SUPPLICANT_STATE_CHANGED_ACTION wifi连接结果通知
WifiManager.NETWORK_STATE_CHANGED_ACTION 网络状态变化通知
只需注册相应的广播类,继承 BroadcastReceiver。就可以进行相关的逻辑处理了。
三,使用
1,首先,注册一个广播并extends BroadcastReceiver。实现onReceive方法。
wifi开关变化
if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) {
//wifi开关变化
int state = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0);
switch (state) {
case WifiManager.WIFI_STATE_DISABLED: {
//wifi关闭
Log.e("=====", "已经关闭");
// tv_wifiState.append("\n 打开变化:wifi已经关闭");
break;
}
case WifiManager.WIFI_STATE_DISABLING: {
//wifi正在关闭
Log.e("=====", "正在关闭");
//tv_wifiState.append("\n 打开变化:wifi正在关闭");
break;
}
case WifiManager.WIFI_STATE_ENABLED: {
//wifi已经打开
Log.e("=====", "已经打开");
// tv_wifiState.append("\n 打开变化:wifi已经打开");
break;
}
case WifiManager.WIFI_STATE_ENABLING: {
//wifi正在打开
Log.e("=====", "正在打开");
// tv_wifiState.append("\n 打开变化:wifi正在打开");
break;
}
case WifiManager.WIFI_STATE_UNKNOWN: {
//未知
Log.e("=====", "未知状态");
// tv_wifiState.append("\n 打开变化:wifi未知状态");
break;
}
}
}
wifi连接状态变化
else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(intent.getAction())) {
//监听wifi连接状态
NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
Log.e("=====", "--NetworkInfo--" + info.toString());
if (NetworkInfo.State.DISCONNECTED == info.getState()) {//wifi没连接上
Log.e("=====", "wifi没连接上");
//tv_wifiState.append("\n 连接状态:wifi没连接上");
} else if (NetworkInfo.State.CONNECTED == info.getState()) {//wifi连接上了
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
//获取当前wifi名称
Log.i("=========", "连接到网络 " + wifiInfo.getSSID());
Log.e("=====", "wifi已连接");
//ToastUtils.showShort("连接到网络 " + wifiInfo.getSSID());
// tv_wifiState.append("\n 连接状态:wifi以连接,wifi名称:" + MyWifiManager.getWiFiName(mWifiManager));
} else if (NetworkInfo.State.CONNECTING == info.getState()) {//正在连接
Log.e("=====", "wifi正在连接");
// tv_wifiState.append("\n 连接状态:wifi正在连接");
}
} else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(intent.getAction())) {
//监听wifi列表变化
Log.e("=====", "wifi列表发生变化");
}
}
2,获取wifimanager的实例
3,注册前面写的广播
4,获取wifi数据
在获取数据之前,先要判断一下wifi开关是否打开。
通过wifimanager中的一个方法进行判断:isWifiEnabled()
若没打开前往设置打开开关:
然后获取wifi数据:
这里可以写一个实体来转换一下 该列表。可以自由发挥。
5.连接wifi
通过wifimanager的方法 connectwifi
分别传入四个参数,实例,SSID,密码,类型
1,注意热点和密码均包含引号,需要转义引号。
2.配置wifi信息,判断加密类型,分别进行配置。此处只列举三种。
3.连接wifi
4.断开连接
调用wifimanager的封装类中的该方法,传入实例即可。
小白记录学习过程,不足之处,请无情