Android自动连接指定的WiFi热点

“Android自动连接指定的WiFi热点”,看上去这是个再基础不过的功能了。很多人都觉得很简单,网上也有大量的资料。但在以Android作为底层系统的硬件设备的连接上,特别针对我们自主开发的轻推投屏盒子为例,这个技术是比较重要的一个点。接下来我就以轻推投屏盒子为例,讲讲Android系统连接WiFi热点的一些难点。

推投屏盒子有两张无线网卡,一个负责对外上网,一个负责对内提供AP局域网。这样的设计是为了在没有外网的环境下也能够实现投屏功能(避免了很多市面上的投屏盒子的缺点。比如必须连接WiFi,并且不支持8021x/eap的WiFi连接),通过连接轻推投屏盒子的AP,实现某些公司需要的公司内网认证。
好了,接下来进入正题,上网WiFi我们使用Android系统的提供WiFi模块管理——WiFiManager。
WiFiManager:是系统提供给开发者使用的系统服务管理类,WifiManager会调用service和framework层, 驱动层进行函数调用,
然后驱动层会回调至上层, 以广播的形式实现通知。简单来说就是,只需要使用WifiManager进行函数操作完成UI, 监听对应的广播消息, 就可完成功能了。
笔者所用到方法:
WiFiManager.startScan():开始扫描WiFi,扫描结果通过广播通知
WiFiManager.disconnect():断开网络WiFi
WiFiManager.addNetwork(WifiConfiguration config):添加WiFi配置,返回networkId
WiFiManager.enableNetwork(networkId, true):允许与以前配置的网络相关联,并尝试连接WiFi
WiFiManager.getScanResults():获取设备缓存的扫描结果,这里部分手机的缓存会很少,跟实际扫描结果不一致,这个时候需要调用一次扫描更新缓存
第一步:获取WiFiManager

WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);

第二步:获取扫描结果缓存
ScanResult.SSID 表示WiFi名,这里需要注意有"",如果界面需要显示,那么得把这个去掉,连接的时候这个得保留才行
ScanResult.BSSID mac,表示WiFi的唯一标识,
ScanResult.frequency 表示WiFi的频率
ScanResult.level 表示WiFi的信号强度,这里为负数,越大表示信号越好

List<ScanResult> scanResults = wifiManager.getScanResults();

第三步:连接WiFi

  /*** wif连接** @param scanResult ScanResult* @param userName String  eap连接需要的用户名* @param pass String  密码* @return 操作结果*/public boolean connectionWifi(ScanResult scanResult,String userName,String pass) {WifiConfiguration config = getWifiConfig(ScanResult scanResult,String userName,String pass);networkId = wifiManager.addNetwork(config);wifiManager.saveConfiguration();return wifiManager.enableNetwork(networkId, true);}

工具方法
判断WiFi类型

/*** 获取wifi安全类型.** @param result ScanResult* @return 0*/public static int getSecurity(ScanResult result) {if (null != result && null != result.capabilities) {if (result.capabilities.contains("WEP")) {return SECURITY_WEP;} else if (result.capabilities.contains("PSK")) {return SECURITY_PSK;} else if (result.capabilities.contains("EAP")) {return SECURITY_EAP;}}return SECURITY_NONE;}

获取wif连接配置

 /*** 获取wif连接配置** @param scanResult ScanResult* @return */public WifiConfiguration getConfig(ScanResult scanResult,String userName,String pass){WifiConfiguration config = new WifiConfiguration();switch(getSecurity(scanResult)){case SECURITY_NONE:initOpenConfig(config);break;case SECURITY_WEP:initWepConfig(scanResult,config,pass);break;case SECURITY_PSK:initPskConfig(scanResult,config,pass);break;case SECURITY_EAP:initEapConfig(scanResult,config,userName,pass);break;}}/*** 初始化公开类型WiFi** @param config WifiConfiguration*/private void initOpenConfig(WifiConfiguration config){config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);}private void initWepConfig(ScanResult scanResult, WifiConfiguration config,String pass) {config.hiddenSSID = true;//安全认证协议config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);//身份验证算法config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);config.wepTxKeyIndex = 0;if (isHexWepKey(pass))config.wepKeys[0] = wifiConnDO.getPassword();//密码elseconfig.wepKeys[0] = convertToQuotedString(pass);//密码}private void initPskConfig(ScanResult scanResult, WifiConfiguration config,String pass) {config.hiddenSSID = true;//公认安全协议config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);//安全认证协议config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);//密码为WPAconfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);//公认的的公共组密码config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);//身份验证算法config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);config.preSharedKey = convertToQuotedString(pass);//密码config.status = WifiConfiguration.Status.ENABLED;}private void initEapConfig(ScanResult scanResult, WifiConfiguration config,String userName,String pass) {config.hiddenSSID = false;//安全认证协议config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);//企业级WiFi的相关信息输入配置WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();enterpriseConfig.setIdentity(wifiConnDO.getUsername());//用户身份enterpriseConfig.setPassword(wifiConnDO.getPassword());//用户密码enterpriseConfig.setAnonymousIdentity("");//匿名身份enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.PEAP);//EAP类型enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE);config.enterpriseConfig = enterpriseConfig;}static boolean isHexWepKey(@Nullable String wepKey) {final int passwordLen = wepKey == null ? 0 : wepKey.length();return passwordLen != 0 && (passwordLen == 10 || passwordLen == 26 || passwordLen == 58) && wepKey.matches("[0-9A-Fa-f]*");}static String convertToQuotedString(@NonNull String string) {if (TextUtils.isEmpty(string))return "";final int lastPos = string.length() - 1;if (lastPos < 0 || (string.charAt(0) == '"' && string.charAt(lastPos) == '"'))return string;return "\"" + string + "\"";}

在我们的实际使用中发现,公司的WiFi有些问题,已经连接过的再次连接的时候会出现连不上的问题,通过对WifiStateMachine的各种日志分析之后发现是我们公司的认证服务有些异常,但这不是我们负责的,所以我们这边采取的方案是,移除配置,然后添加新的配置,问题成功解决。
获取已经系统保存的WiFi配置信息和新的连接方法

protected boolean connectionWifi(WifiConnDO wifiConnDO) {//获取已保存的WiFi配置WifiConfiguration config = getSaved(wifiConnDO);int networkId;if (config != null) {networkId = config.networkId;//移除以保存的配置并保存操作wifiManager.removeNetwork(networkId);wifiManager.saveConfiguration();}//获取WiFi配置config = getWifiConfig(wifiConnDO);
//        config.BSSID = wifiConnDO.getBssid();//添加并保存配置networkId = wifiManager.addNetwork(config);wifiManager.saveConfiguration();//使用WiFireturn wifiManager.enableNetwork(networkId, true);;}
private WifiConfiguration getSaved(ScanResult result) {List<WifiConfiguration> existingConfigs = wifiManager.getConfiguredNetworks();if (existingConfigs == null) {return null;}for (WifiConfiguration existingConfig : existingConfigs) {if (existingConfig.SSID.equals(result.SSID)) {return existingConfig;}}return null;}

关于连接WiFi的广播部分这里就不做过多说明了,与其他技术博客的一样即可。
整个过程中我们遇到很多问题,诸如上网芯片支持的频道过少发现不了公司5GWiFi的信道,公司WiFi上网定期会断之后重新连接会切到其他BSSID的同名WiFi导致上网速度慢…
有疑问和指教的地方请私联:long.zhao@cisdi.com.cn

Android自动连接指定的WiFi热点相关推荐

  1. android 开发 自动生成wifi,Android编程开发:自动连接指定SSID的wifi热点

    在Android编程开发中,最近在做一个项目,其中涉及到一块"自动连接已存在的wifi热点"的功能,在网上查阅了大量资料,五花八门,但其中一些说的很简单,即不能实现傻瓜式的拿来就用 ...

  2. Android开发——自动连接指定SSID的wifi热点(不加密/加密)

    最近在做一个项目,其中涉及到一块"自动连接已存在的wifi热点"的功能,在网上查阅了大量资料,五花八门,但其中一些说的很简单,即不能实现傻瓜式的拿来就用,有些说的很详细,但其中不乏 ...

  3. Android下自动连接指定SSID的WIFI的简单实现

    一.关于WiFi模块的概述: 1.在Android developer的文档中WiFi模块的信息: 首先,登记广播的监听:其次,请求扫描wifi信号:最后获取扫描到的wifi信息. 2.在广播监听到结 ...

  4. Android Wifi --自动连接指定SSID(各种加密方式均可)

    Android Wifi API参考网站这里写链接内容 1.开始先加入wifi权限 <uses-permission android:name="android.permission. ...

  5. android 图片热点区域,Android开发之扫描附近wifi热点并列表显示

    最近项目中用到了wifi模块,今天做一个简单的总结. 参考:http://www.2cto.com/kf/201310/253617.html 1.怎样获取wifi对象并进行操作 要操作WIFI设备, ...

  6. 树莓派3B+不能连接5G的Wi-Fi热点

    树莓派3B+不能连接5G的Wi-Fi热点原因 打开raspberry pi configuration 打开raspberry pi configuration 在localization页面,看到w ...

  7. android自动直接连接到指定wifi,Android 连接指定的wifi

    今天来点干货,讲讲如何通过代码连接上指定的wifi.相当于使用代码完成使用者在手机WLAN中选择wifi,并且输入密码,然后点击确定的过程. 既然要操纵wifi,就需要使用到wifiManager,我 ...

  8. 安卓java修改热点_修改Android源码实现连接指定BSSID的热点

    1 概述 需要实现一个需求,Android手机A发射热点,获取BSSID,发送到另一台Android设备,在环境中存在多个同样SSID和密码的情况下,设备只会连接手机A. 1.1 概念 服务集识别码( ...

  9. android wifi取消自动连接网络,Android 11新增无线网络连接安全策略 可以不自动连接某些特定WiFi...

    多数网络设备在初次连接某个无线网络后会记住密码并在下次自动连接,对多数用户来说这可能是比较好的策略. 毕竟这样不需要用户下次主动查询无线网络再连接,不过苹果倒是很早就在iOS 里提供不自动连接无线网的 ...

最新文章

  1. usaco window arear(递归求矩形覆盖面积)
  2. 关于srand 和 rand 随机数的产生的注意事项
  3. C语言变参函数的实现,C语言的那些小秘密之变参函数的实现
  4. 抛弃PHP,WordPress.com以JavaScript重写
  5. 使用牛刀云开发微信小程序(问题集锦)
  6. android 按键上浮动画_android – 浮动动作按钮动画
  7. python训练聊天机器人_一个可以进行训练的聊天机器人,一次chat的源码
  8. excel快速填充_F4键,Excel中最强大的快捷键,没有之一
  9. 中国磷矿市场趋势报告、技术动态创新及市场预测
  10. .Net下二进制形式的文件(图片)的存储与读取(转载)
  11. Spring的AOP中的责任链模式
  12. 小觅相机运行VINS-Fusion(三)——IMU的标定
  13. Android随机点名器,Excel基础知识-详解随机点名器
  14. IOS内存泄漏动静态方法排查
  15. GE CimplicityV11.1安装步骤
  16. 【推荐系统】基于协同过滤的图书推荐系统
  17. 关于移动端使用position:fixed/absolute出现随屏幕滚动情况
  18. Marvelous Necklace Gym - 102020M
  19. 读懂python中的self
  20. Python实现逻辑回归

热门文章

  1. 常见窄带宽带音频编码格式
  2. 一个计算机系统常用的流水线形式有,计算机系统结构作业答案第三章(张晨曦)...
  3. 一文带你学会微信V3版本下单支付、退款、关单流程代码实操
  4. 学期计划,大学生活,所得所失
  5. 免费rar/zip解压缩工具BandZip
  6. 华为服务器告警显示风扇不在位,华为机架服务器RH2285 运行时噪声很大故障的解决...
  7. 写论文前你必须知道的十大论文类型和五大研究方法
  8. python嵌套循环跳出_python 行使 for ... else 跳出双层嵌套循环_rust辅助,彩虹六号辅助...
  9. 波士顿动力SpotMini机器狗大秀舞技,节奏感十足
  10. 如何免费用微信小程序中文 AI 绘画?