前言
最近在Android11
上开发了WiFi
相关功能,涉及到WiFi
列表的获取、连接有密码的WiFi
、连接已保存的WiFi
、忘记连接的WiFi
、添加其他WiFi
。涉及到的知识点较多作以分篇记录,本篇将介绍WiFi
列表的获取与展示。
说明
下面梳理下WiFi
列表获取流程:
- 判断
WiFi
开关是否打开(假设打开-Y) - 打开情况显示
WiFi
列表布局 - 判断当前是否有扫描任务(假设没有-N)
- 开启扫描动画、延时20S后开始扫描可用
WiFi
(时间根据需求定义)、获取当前连接的WiFi
- 接收到扫描结果广播
- 停止扫描动画、对获取
WiFi
列表进行过滤 - 通知
WiFi
列表刷新 - 不延时扫描可用
WiFi
、获取当前连接的WiFi
实现
上述介绍了WiFi
扫描获取流程,下面将介绍相关的API
和功能实现。
Android
中提供了WifiManager
类用来管理WiFi
。
1、WifiManager对象的获取:
private val wifiManager:WifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
2、判断WiFi是否使能
/**
* WiFi开关是否使能
*/
fun isWiFiEnabled(): Boolean {
return wifiManager.isWifiEnabled
}
/**
* 设置WiFi开关是否使能
*/
fun setWiFiEnable(enable: Boolean) {
wifiManager.isWifiEnabled = enable
}
3、扫描WiFi
调用WifiManager
的startScan()
方法,即可开启对WiFi
扫描。此方法已标记为遗弃,但是目前版本可以使用。
/**
* 开启扫描WiFi事件
*/
fun startScan(): Boolean {
return wifiManager.startScan()
}
4、扫描WiFi结果广播
Android
WiFi
扫描结果提供了对外广播,监听此广播、接收到以后进行业务操作。
WifiManager:
public static final String SCAN_RESULTS_AVAILABLE_ACTION = "android.net.wifi.SCAN_RESULTS";
5、获取扫描结果
注册上述广播,有回调后表示扫描结束,通过wifiManager.getScanResults
获取扫描到的WiFi
列表。
val wifiList = wifiManager.scanResults as ArrayList<ScanResult>
通过上述方法获取的WiFi
列表需要进行过滤才能进行展示,过滤条件有以下几点:
- 过滤同一
WiFi
:扫描结果中同一个WiFi
可能会返回多次,集合中存在多个。 - 过滤名字为空的
WiFi
:判断当前WiFi名是否为空,为空不添加新的集合中。 - 过滤当前连接的
WiFi
:列表中不显示当前连接的WiFi
。 - 过滤设备自发的热点:列表中不显示设备自发热点。
- 按信号强弱排列:根据
WiFi
信号强度从高到低排列。
继续了解WifiManager
中提供的相关方法。
6、获取当前连接的WiFi信息
通过wifiManager.getConnectionInfo()
可以获取当前连接的WiFi
信息。
/**
* 获取当前连接的WiFi名称
*/
fun getSSID(): String? {
val wifiInfo = wifiManager.connectionInfo
if (wifiInfo != null) {
val s = wifiInfo.ssid
if (s.length > 2 && s.toCharArray()[0] == '"' && s.toCharArray()[s.length - 1] == '"') {
return s.substring(1, s.length - 1)
}
}
return null
}
7、WiFi信号强度排序
上面提到了WiFi
扫描结果的获取,信号强度level
通过扫描结果对象ScanResult
中获取。
/**
* 通道频率
*/
public static final int CHANNEL_WIDTH_160MHZ = 3;
public static final int CHANNEL_WIDTH_20MHZ = 0;
public static final int CHANNEL_WIDTH_40MHZ = 1;
public static final int CHANNEL_WIDTH_80MHZ = 2;
public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4;
/**
* WiFi频段
*/
public static final int UNSPECIFIED = -1;
public static final int WIFI_BAND_24_GHZ = 1;
public static final int WIFI_BAND_5_GHZ = 2;
public static final int WIFI_BAND_60_GHZ = 16;
public static final int WIFI_BAND_6_GHZ = 8;
//访问点的Mac地址
public String BSSID;
//WiFi名称
public String SSID;
//描述了身份验证、密钥管理和访问点支持的加密方案
public String capabilities;
//带宽
public int channelWidth;
//主20 MHz的频率(MHz)的渠道客户交流访问点
public int frequency;
//信号强度,也称RSSI
public int level;
8、WiFi状态获取
提供了广播WIFI_STATE_CHANGED_ACTION
来监听WiFi
状态的改变,通过通wifiManager.getWifiState()
来获取当前WiFi
状态。
WifiManager:
public static final String WIFI_STATE_CHANGED_ACTION = "android.net.wifi.WIFI_STATE_CHANGED";
public static final String EXTRA_WIFI_STATE = "wifi_state";
/**
* 获取WiFi状态
*/
fun getState(): Int {
return wifiManager.wifiState
}
对WiFi
开关、列表UI
、WiFi
相关信息的显示与隐藏的操作,可以在WiFi
状态切换中来修改。
在WiFi列表获取和WiFi状态
/**
* 网络相关广播
*/
class WiFiBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if(App.DEBUG) Log.i(TAG,"[onReceive] action = ${intent.action}")
when (intent.action) {
WifiManager.WIFI_STATE_CHANGED_ACTION -> {
if(App.DEBUG) Log.i(TAG,"WIFI_STATE_CHANGED_ACTION")
val wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_DISABLED)
stateChange(wifiState)
}
WifiManager.SCAN_RESULTS_AVAILABLE_ACTION -> {
if(App.DEBUG) Log.i(TAG,"SCAN_RESULTS_AVAILABLE_ACTION")
//停止扫描任务
cancelScanTask()
//停止扫描动画
stopAnimation()
//获取wifi列表并过滤返回
val wifiList = WiFiUtils.scanWiFiListResult()
//通知列表刷新
notifyWiFiList(wifiList)
}
}
}
}
fun stateChange(state:Int){
when(state){
//WiFi正在关闭中...
WifiManager.WIFI_STATE_DISABLING ->{
}
//WiFi已经关闭
WifiManager.WIFI_STATE_DISABLED ->{
}
//WiFi正在打开中...
WifiManager.WIFI_STATE_ENABLING ->{
}
//WiFi已经打开
WifiManager.WIFI_STATE_ENABLED ->{
}
}
结尾
上述介绍了Android11
中WiFi
列表的获取流程与对应的API
方法,下篇文章介绍对WiFi
的相关操作,连接与断开连接、获取WiFi
信息等。