Android-WiFi开发之 WifiManager

前言:

作为一名系统开发者, 对应用上 WiFi 的研发是一个 "门外汉" 的角色, 通过阅读 Android 源码, 逐渐对这一部分有了些许认识. 下方主要围绕 WifiManager 的函数系, 做了一些类似工具类的封装, 语言尽量简单, 希望对各位系统开发者能起到帮助的作用, 具体内容以 解释 + 注释 + 代码块的形式展示给大伙.

  1. 简介: WifiManager这个类, 是 Android 暴露给开发者使用的一个系统服务管理类, 其中包含对WiFi的响应的操作函数; 其隐藏掉的系统服务类为IWifiService, 为Android私有的, 其具体实现, 未暴露给用户; 只需要使用WifiManager进行函数操作完成UI, 监听对应的广播消息, 就可完成功能了. 换言之, WifiManager会调用service简介地和framework层, 驱动层进行函数调用, 然后驱动层会回调至上层, 以广播的形式实现通知; 这是目前WiFi的简单介绍;

  2. 一些简单的工具类的封装 以及 简要说明:

  • 获取 WifiManager 实例:
 
  1. // 获取 WifiManager 实例.

  2. public static WifiManager getWifiManager(Context context) {

  3. return context == null ? null : (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);

  4. }

注意: 这是官方推荐的获取 WifiManager 类的方式; 其实在看源码的时候, 会有一个公共的构造函数, 但是是需要IWifiService的, 这个类是google私有的, 属于系统安全级别的API类, 所以, 调用上面的方法, 谷歌会帮你实例化IWifiService, 并且后续的连接, 忘记, 保存的真实实现都是由service来完成的;

  • 开启, 关闭 WiFi: (操作这个函数的时候, 就会触发系统回调WiFi状态发生改变的广播)
 
  1. // 开启/关闭 WIFI.

  2. public static boolean setWifiEnabled(WifiManager manager, boolean enabled) {

  3. return manager != null && manager.setWifiEnabled(enabled);

  4. }

  • 获取 WiFi 硬件的状态:
 
  1. // 获取 WIFI 的状态.

  2. public static int getWifiState(WifiManager manager) {

  3. return manager == null ? WifiManager.WIFI_STATE_UNKNOWN : manager.getWifiState();

  4. }

  5.  
  6. /**

  7. * 注意:

  8. * WiFi 的状态目前有五种, 分别是:

  9. * WifiManager.WIFI_STATE_ENABLING: WiFi正要开启的状态, 是 Enabled 和 Disabled 的临界状态;

  10. * WifiManager.WIFI_STATE_ENABLED: WiFi已经完全开启的状态;

  11. * WifiManager.WIFI_STATE_DISABLING: WiFi正要关闭的状态, 是 Disabled 和 Enabled 的临界状态;

  12. * WifiManager.WIFI_STATE_DISABLED: WiFi已经完全关闭的状态;

  13. * WifiManager.WIFI_STATE_UNKNOWN: WiFi未知的状态, WiFi开启, 关闭过程中出现异常, 或是厂家未配备WiFi外挂模块会出现的情况;

  14. */

  • 开始扫描 WiFi 热点, 在确认开启 WiFi 之后, 我们就可以调用 startScan() 函数开始扫描附近的热点了, 即:
 
  1. // 开始扫描 WIFI.

  2. public static void startScanWifi(WifiManager manager) {

  3. if (manager != null) {

  4. manager.startScan();

  5. }

  6. }

  • 获取扫描到的 WiFi 热点的结果:
 
  1. // 获取扫描 WIFI 的热点:

  2. public static List<ScanResult> getScanResult(WifiManager manager) {

  3. return manager == null ? null : manager.getScanResult();

  4. }

  • 获取配置好的 WiFi 信息:
 
  1. // 获取已经保存过的/配置好的 WIFI 热点.

  2. public static List<WifiConfiguration> getConfiguredNetworks(WifiManager manager) {

  3. return manager == null ? null : manager.WifiConfiguration();

  4. }

  5.  
  6. /**

  7. * 注意:

  8. * Android 的 WiFi 连接, 大概可以分为如下两种情况:

  9. * a. 无密码的, 可直接连接, 连接过程中, 此热点一直有, 不管最后是否需要其他方式进行验证操作, 但凡连接成功, 即

  10. * 刻进行了对此热点的配置进行保存;

  11. * b. 有密码的, 暂且不论何种加密手段, 只要用户输入密码, 点击连接, 如果连接途中, 此热点一直有, 不论连接成功还

  12. * 是失败, 都即刻对此热点的配置进行了保存操作; 使用上述的方式获取到的WiFi的配置, 就是上面进行操作保存的WiFi配

  13. * 置;

  14. * c. 连接多个WiFi成功之后, 然后关闭WiFi, 下次开启WiFi的时候, 驱动会主动帮你连接这其中配置好的其中一个WiFi;

  15. * /

  16.  
  • 获取对应到 ScanResult 的 WifiConfiguration, 通常, 此配置对应一个 BSSID, 可能是 null;
 
  1. List<WifiConfiguration> configs = wifiManager.getMatchingWifiConfig(scanResult);

  2.  
  3. // 可以打印一下看具体的情况:

  4. if (configs == null || configs.isEmpty()) return;

  5. for (WifiConfiguration config : configs) {

  6. Log.v(TAG, "config = " + config);

  7. }

  • 连接WiFi: 连接 WIFI, 安卓提供了两种方式, 一种是通过配置连接, 另一种是通过 networkId 来连接, 两种方式各有使用场景, 可根据需要选择使用, 封装后的函数如下: (反射可抽取方法, 单独提炼, 此处不展示.)
 
  1. // 使用 WifiConfiguration 连接.

  2. public static void connectByConfig(WifiManager manager, WifiConfiguration config) {

  3. if (manager == null) {

  4. return;

  5. }

  6. try {

  7. Method connect = manager.getClass().getDeclaredMethod("connect", WifiConfiguration.class, Class.forName("android.net.wifi.WifiManager$ActionListener"));

  8. if (connect != null) {

  9. connect.setAccessible(true);

  10. connect.invoke(manager, config, null);

  11. }

  12. } catch (Exception e) {

  13. e.printStackTrace();

  14. }

  15. }

  16.  
  17. // 使用 networkId 连接.

  18. public static void connectByNetworkId(WifiManager manager, int networkId) {

  19. if (manager == null) {

  20. return;

  21. }

  22. try {

  23. Method connect = manager.getClass().getDeclaredMethod("connect", int.class, Class.forName("android.net.wifi.WifiManager$ActionListener"));

  24. if (connect != null) {

  25. connect.setAccessible(true);

  26. connect.invoke(manager, networkId, null);

  27. }

  28. } catch (Exception e) {

  29. e.printStackTrace();

  30. }

  31. }

  • 保存网络:
 
  1. // 保存网络.

  2. public static void saveNetworkByConfig(WifiManager manager, WifiConfiguration config) {

  3. if (manager == null) {

  4. return;

  5. }

  6. try {

  7. Method save = manager.getClass().getDeclaredMethod("save", WifiConfiguration.class, Class.forName("android.net.wifi.WifiManager$ActionListener"));

  8. if (save != null) {

  9. save.setAccessible(true);

  10. save.invoke(manager, config, null);

  11. }

  12. } catch (Exception e) {

  13. e.printStackTrace();

  14. }

  15. }

  • 添加网络:
 
  1. // 添加网络.

  2. public static int addNetwork(WifiManager manager, WifiConfiguration config) {

  3. if (manager != null) {

  4. manager.addNetwork(config);

  5. }

  6. }

  • 忘记网络:
 
  1. // 忘记网络.

  2. public static void forgetNetwork(WifiManager manager, int networkId) {

  3. if (manager == null) {

  4. return;

  5. }

  6. try {

  7. Method forget = manager.getClass().getDeclaredMethod("forget", int.class, Class.forName("android.net.wifi.WifiManager$ActionListener"));

  8. if (forget != null) {

  9. forget.setAccessible(true);

  10. forget.invoke(manager, networkId, null);

  11. }

  12. } catch (Exception e) {

  13. e.printStackTrace();

  14. }

  15. }

  • 禁用网络:
 
  1. // 禁用网络.

  2. public static void disableNetwork(WifiManager manager, int netId) {

  3. if (manager == null) {

  4. return;

  5. }

  6. try {

  7. Method disable = manager.getClass().getDeclaredMethod("disable", int.class, Class.forName("android.net.wifi.WifiManager$ActionListener"));

  8. if (disable != null) {

  9. disable.setAccessible(true);

  10. disable.invoke(manager, networkId, null);

  11. }

  12. } catch (Exception e) {

  13. e.printStackTrace();

  14. }

  15. }

  • 断开连接:
 
  1. // 断开连接.

  2. public static boolean disconnectNetwork(WifiManager manager) {

  3. return manager != null && manager.disconnect();

  4. }

  • 短暂禁用网络:
 
  1. // 禁用短暂网络.

  2. public static void disableEphemeralNetwork(WifiManager manager, String SSID) {

  3. if (manager == null || TextUtils.isEmpty(SSID))

  4. return;

  5. try {

  6. Method disableEphemeralNetwork = manager.getClass().getDeclaredMethod("disableEphemeralNetwork", String.class);

  7. if (disableEphemeralNetwork != null) {

  8. disableEphemeralNetwork.setAccessible(true);

  9. disableEphemeralNetwork.invoke(manager, SSID);

  10. }

  11. } catch (Exception e) {

  12. e.printStackTrace();

  13. }

  14. }

小结:

  1. 如上, 针对会使用到的函数做个简单的封装, 使大家用起来更加简单明了, 希望能带给你一些方便.

  2. 如有疑问, 请简信, 或邮箱告知. 亦可下方评论区留言.

  3. outlook 邮箱: Benjie1017@outlook.com

  4. qq 邮箱: 1281641968@qq.com



作者:迷你小猪
链接:https://www.jianshu.com/p/67aaf1fdb921
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值