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 还持有它的引用,导致内存泄漏。嗯,这种坑踩过一次就记住了。

💡 我的建议: 在 Application 类里封装一个静态方法,全局统一获取 WiFiManager。这样整个 App 都只用这一个实例,既省资源又安全。

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,别偷懒。

⚠️ 注意: Android 10(API 29)之后,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 入门阶段的核心流程:

WiFiManager 入门核心流程 1. 获取 WiFiManager 实例 2. 检查 WiFi 状态 是否已开启? 继续后续操作 打开/关闭 WiFi 注意:Android 10+ 普通 App 无法直接调用 setWifiEnabled()

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(),而是通过 WifiManagerstartScan()getScanResults() 来获取周围热点列表,然后让用户自己选择连接。这样既避免了权限问题,又符合用户预期。说白了,尊重用户的选择权,才是好的设计。

好了,这一节的内容就到这里。WiFiManager 的获取、状态检查和开关操作,是后续所有 WiFi 功能的基础。把这些搞清楚了,后面讲扫描、连接、配置等高级操作时,你才不会觉得吃力。

记住一句话:拿到实例是前提,检查状态是习惯,开关操作要谨慎。尤其是权限问题,Android 版本越新限制越多,提前做好兼容处理,能省去很多麻烦。


公众号:蓝海资料掘金营,微信 deep3321