4. WiFiManager 入门:获取实例、检查状态、开关 WiFi
好,咱们正式开始动手操作 WiFi 模块。
前面几章讲了 Android WiFi 的整体架构和权限,算是热身。从这一节开始,我们要真正跟 WiFiManager 打交道了。这是 Android 提供给我们操作 WiFi 的核心 API,说白了,它就是系统 WiFi 服务的“遥控器”。
4.1 获取 WiFiManager 实例
在 Android 里,想拿到系统服务,通常都是通过 Context.getSystemService() 来获取。WiFiManager 也不例外。
我个人习惯在 Application 或者 Activity 的初始化阶段就把这个实例拿到手,避免到处重复写获取代码。你想想看,如果每个页面都写一遍,后期维护起来多麻烦。
// 获取 WiFiManager 实例
WiFiManager wifiManager = (WiFiManager) getApplicationContext()
.getSystemService(Context.WIFI_SERVICE);
这里有个细节要注意:一定要用 Application Context,而不是 Activity 的 Context。为什么?因为 WiFiManager 实例跟 Activity 的生命周期没关系,用 Application Context 可以防止内存泄漏。我在项目中遇到过有人用 Activity 的 Context 去拿 WiFiManager,结果 Activity 销毁了,但 WiFiManager 还持有它的引用,导致内存泄漏。嗯,这种坑踩过一次就记住了。
4.2 检查 WiFi 状态:isWifiEnabled()
拿到 WiFiManager 之后,第一件事通常是检查 WiFi 开关是否打开。方法很简单:
boolean isEnabled = wifiManager.isWifiEnabled();
if (isEnabled) {
// WiFi 已开启,可以继续操作
} else {
// WiFi 已关闭,提示用户或自动打开
}
这个方法返回的是布尔值,true 表示 WiFi 已启用,false 表示已禁用。
不过,这里有个容易忽略的点:isWifiEnabled() 返回的是 当前 WiFi 硬件的开关状态,而不是网络连接状态。换句话说,它只告诉你 WiFi 模块有没有通电工作,不告诉你有没有连上某个热点。这两个概念千万别搞混了。
我曾经在项目里看到新人把 isWifiEnabled() 当成“是否已连接网络”来判断,结果 WiFi 开着但没连上任何热点,App 却认为网络可用,直接去请求数据,导致各种超时异常。所以,判断网络连通性要用 NetworkInfo 或者 ConnectivityManager,别偷懒。
isWifiEnabled() 在某些设备上可能返回不准确的状态。建议结合 WifiManager.WIFI_STATE_ENABLED 常量来双重确认。
4.3 打开/关闭 WiFi:setWifiEnabled()
接下来是开关 WiFi 的操作。Android 提供了 setWifiEnabled(boolean enabled) 方法:
// 打开 WiFi
boolean success = wifiManager.setWifiEnabled(true);
// 关闭 WiFi
boolean success = wifiManager.setWifiEnabled(false);
这个方法返回一个布尔值,表示操作是否成功提交。注意,我说的是“提交”,不是“完成”。因为开关 WiFi 是一个异步过程,系统需要时间跟底层硬件通信。所以 setWifiEnabled() 返回 true 只代表你的请求被系统接收了,不代表 WiFi 已经真的打开或关闭了。
那怎么知道最终状态呢?需要监听 WifiManager.WIFI_STATE_CHANGED_ACTION 广播。这个我们后面会详细讲,这里先提一嘴。
setWifiEnabled()是同步调用,但结果是异步生效的- 调用后立即检查
isWifiEnabled()可能还是旧状态 - Android 10 之后,普通 App 可能无法直接调用此方法(需要系统权限)
说到权限,这里必须强调一下:从 Android 10 开始,Google 收紧了 WiFi 相关的权限。普通第三方 App 调用 setWifiEnabled() 会直接抛出安全异常,除非你的 App 是系统应用或者有 SYSTEM_ALERT_WINDOW 权限。说白了,Google 不希望普通 App 随意开关用户的 WiFi,这是为了保护用户隐私和体验。
那如果我们的 App 确实需要开关 WiFi 怎么办?我的做法是:引导用户去系统设置页面手动操作,或者使用 Settings.Panel.ACTION_WIFI 打开 WiFi 设置面板。这样既合规,用户体验也不差。
// 打开 WiFi 设置面板(Android 10+ 推荐方式)
Intent panelIntent = new Intent(Settings.Panel.ACTION_WIFI);
startActivity(panelIntent);
4.4 本章知识体系图
下面这张图帮你理清 WiFiManager 入门阶段的核心流程:
4.5 常见问题与避坑指南
| 问题 | 原因 | 解决方案 |
|---|---|---|
| getSystemService 返回 null | Context 类型不对或设备不支持 WiFi | 使用 Application Context,并检查设备是否支持 WiFi |
| isWifiEnabled 返回 false 但 WiFi 实际已开 | 权限不足或系统限制 | 检查是否声明了 ACCESS_WIFI_STATE 权限 |
| setWifiEnabled 抛出 SecurityException | Android 10+ 权限收紧 | 改用 Settings Panel 或引导用户手动操作 |
| 开关 WiFi 后状态不更新 | 异步操作,未监听状态变化广播 | 注册 WIFI_STATE_CHANGED_ACTION 广播接收器 |
setWifiEnabled(),而是通过 WifiManager 的 startScan() 和 getScanResults() 来获取周围热点列表,然后让用户自己选择连接。这样既避免了权限问题,又符合用户预期。说白了,尊重用户的选择权,才是好的设计。
好了,这一节的内容就到这里。WiFiManager 的获取、状态检查和开关操作,是后续所有 WiFi 功能的基础。把这些搞清楚了,后面讲扫描、连接、配置等高级操作时,你才不会觉得吃力。
记住一句话:拿到实例是前提,检查状态是习惯,开关操作要谨慎。尤其是权限问题,Android 版本越新限制越多,提前做好兼容处理,能省去很多麻烦。