前言

三月份新入职的公司,公司的主要业务是只能电视应用,由于公司战略需要,准备做一个tvos,里面包含有设置的系统应用,本人分到的任务是wifi这一块开发。由于之前接手的都是移动端的开发,对于wifi这一块几乎没有接触过,所以分享出来,希望我踩过的坑,大家能避免。

正文

 wifi扫描:

首先,要对设备的网络情况就行修改,就要获得相应的权限:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /><!-- 允许程序改变网络链接状态 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><!--允许程序访问访问WIFI网络状态信息  -->复制代码

 然后,接收网络变化的广播:

public class WifiBroadcastReceiver extends BroadcastReceiver {private IntentFilter filter;private Context context;private WifiStateChangeListener wifiStateChangeListener;public WifiBroadcastReceiver(Context context) {this.context = context;filter = new IntentFilter();filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);//wifi开关变化广播filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);//热点扫描结果通知广播filter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);//—热点连接结果通知广播filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);  //—网络状态变化广播(与上一广播协同完成连接过程通知)filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);context.registerReceiver(this, filter);}@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (null != wifiStateChangeListener) {wifiStateChangeListener.onWifiChange(intent);}}public void unRegister() {context.unregisterReceiver(this);}public void setWifiStateChangeListener(WifiStateChangeListener wifiStateChangeListener) {this.wifiStateChangeListener = wifiStateChangeListener;}public interface WifiStateChangeListener {/***/void onWifiChange(Intent action);}}复制代码

通过不同广播的action,进行相应的处理:

@Override
public void onWifiChange(Intent action) {switch (action.getAction()) {case WifiManager.WIFI_STATE_CHANGED_ACTION:checkWfiState(action);break;case WifiManager.SCAN_RESULTS_AVAILABLE_ACTION:getScanResult();break;case WifiManager.SUPPLICANT_STATE_CHANGED_ACTION:int error = action.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, 0);if (WifiManager.ERROR_AUTHENTICATING == error) {toastFail();} else {checkWifiConnectState(action);}break;default://网线if (NetInfoUtil.isEthernet()) {finish();}break;}}
复制代码

接下来打开wifi,

//开启或者关闭WIFI
public void openWifi(boolean isEnable) {if (!isEnable) {removeConnecting();}wifiManager.setWifiEnabled(isEnable);
}复制代码

如果wifi以及打开就开始扫描wifi信号:

private void checkWfiState(Intent intent) {
//获取当前wifi的状态int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,WifiManager.WIFI_STATE_DISABLED);switch (wifiState) {case WifiManager.WIFI_STATE_DISABLED://wifi已关闭connectState = WifiConnectState.NONE;wifiSwitchView.setEnabled(true);wifiSwitchView.setWifiOpened(false);stopScanWifi();break;case WifiManager.WIFI_STATE_ENABLED://wifi已打开startScanWifi(true);wifiSwitchView.setEnabled(true);wifiSwitchView.setWifiOpened(true);break;case WifiManager.WIFI_STATE_ENABLING:wifiSwitchView.setEnabled(false);//wifi正在打开break;case WifiManager.WIFI_STATE_DISABLING:wifiSwitchView.setEnabled(false);//wifi正在关闭break;default:break;}
}复制代码

开始扫描wifi:

/*** 开始扫描Wifi*/
private void startScanWifi(boolean isLoading) {if (isLoading) {showLoadingDialog("");}wifiManager.startScan();
}复制代码

Wifi扫描成功之后,会发出一个WifiManager.SCAN_RESULTS_AVAILABLE_ACTION

的广播。通过List<ScanResult> scanResults = wifiManager.getScanResults();

获取扫描结果,接下来看下ScanResult这个类,其中SSID,表示是wifi的名称。capabilities描述了wifi的加密方式等信息,可以通过如下方式判断wifi的加密方式:

if (model.capabilities.contains("WPA") || model.capabilities.contains("wpa")) {encryptType = TYPE_ENCRYPT_WPA;
} else if (model.capabilities.contains("WEP") || model.capabilities.contains("wep")) {encryptType = TYPE_ENCRYPT_WEP;
} else {encryptType = "";
}复制代码

不同的加密方式,连接的处理方式第不一样的。level是表示wifi的信号强度,一般是个负数,越大表示信号越强。

wifi连接:

首先判读wifi是否已保存,如果以及保存,那么不需要输入密码直接连接,通过如下方法判读wifi是否保存:

private WifiConfiguration getExistConfig(String ssid) {List<WifiConfiguration> existingConfigs = wifiManager.getConfiguredNetworks();if (!CollectionUtil.isEmpty(existingConfigs)) {for (WifiConfiguration existingConfig : existingConfigs) {if (TextUtil.isEquals(existingConfig.SSID, ssid))return existingConfig;}}return null;}复制代码

wifiManager.getConfiguredNetworks()会把所有已经保存的wifi,返回,如果扫描出的wifi吗名称,能够在.getConfiguredNetworks()找到证明是已保存的。通过如下方法连接wifi:

int netId = wifiManager.addNetwork(config);
//WifiManager的enableNetwork接口,就可以连接到netId对应的wifi了
//其中boolean参数,主要用于指定是否需要断开其它Wifi网络
wifiManager.enableNetwork(netId, true);复制代码

如果wifi没有保存,那么有自己构造WifiConfiguration,如下:

public WifiConfiguration createWifiConfig(WifiScanResultVM wifiScanResultVM) {//初始化WifiConfigurationWifiConfiguration config = new WifiConfiguration();config.SSID = wifiScanResultVM.getSsid();//不需要密码的场景String password = wifiScanResultVM.getPassWord();if (!wifiScanResultVM.isEncrypt()) {config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);//以WEP加密的场景} else if (TextUtil.isEquals(wifiScanResultVM.getEncryptType(), WifiScanResultVM.TYPE_ENCRYPT_WEP)) {int i = password.length();if (((i == 10 || (i == 26) || (i == 58))) && (password.matches("[0-9A-Fa-f]*"))) {config.wepKeys[0] = password;} else {config.wepKeys[0] = "\"" + password + "\"";}//以WPA加密的场景,自己测试时,发现热点以WPA2建立时,同样可以用这种配置连接} else if (TextUtil.isEquals(wifiScanResultVM.getEncryptType(), WifiScanResultVM.TYPE_ENCRYPT_WPA)) {config.preSharedKey = "\"" + password + "\"";config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);}return config;
}复制代码

需要区分不同的加密方式,连接过程中会多次发出,WifiManager.SUPPLICANT_STATE_CHANGED_ACTION

这个广播,处理如下:

int error = action.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, 0);
if (WifiManager.ERROR_AUTHENTICATING == error) {toastFail();
} else {checkWifiConnectState(action);
}复制代码
 /*** wifi切换连接** @param intent*/public void checkWifiConnectState(Intent intent) {SupplicantState supplicantState = intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE);if (null != supplicantState) {switch (supplicantState) {case DISCONNECTED:connectState = WifiConnectState.NONE;getScanResult();break;case COMPLETED:
//                    if (currentData != null) {
//                        XLog.e("SSID", "checkWifiConnectState" + currentData.getSsid());
//                    }getScanResult();connectState = WifiConnectState.CONNECTED;break;}return;}}复制代码

还有一个问题,如何判断当前正在连接的是哪个wifi,如下:

 private String getCurrentSsid() {
//        XLog.e("SSID", "getCurrentSsid: ");if (connectState != WifiConnectState.CONNECTED) {
//            XLog.e("SSID", " WifiConnectState.CONNECTED: " + connectState.name());return "";}WifiInfo wifiInfo = wifiManager.getConnectionInfo();if (wifiInfo != null) {
//            XLog.e("SSID", "wifiInfo" + wifiInfo.getSSID());return wifiInfo.getSSID();}
//        XLog.e("SSID", "null null null  ");return "";}复制代码

通过拿到当前wifi的连接信息进行比对,有个问题值得注意,当前wifi正在连接时,

 WifiInfo wifiInfo = wifiManager.getConnectionInfo();复制代码

返回的也是有值得,需要注意下。

未填的坑:

当有两个wifi名称一样的时候,就不好处理,这边的处理是直接忽略一个,如果有大神有好的方案,欢迎留言,大家一起讨论下

Android设备wifi开发相关推荐

  1. android获取wifi连接状态,获取android设备wifi连接状态

    本文将介绍如何获取android设备wifi连接状态! 添加访问权限(AndroidManifest.xml文件里) Java代码(MainActivity.java文件) package com.e ...

  2. android进入wifi权限,判断android设备wifi连接状态,判断android设备wifi,添加访问权限(Andro...

    判断android设备wifi连接状态,判断android设备wifi,添加访问权限(Andro 添加访问权限(AndroidManifest.xml文件里) ```Java代码(MainActivi ...

  3. android设备wifi无线adb调试

    android设备wifi无线adb调试 1, 在Window 10上,Win徽标->打开Windows设置->网络和Internet->移动热点->打开移动热点 2, and ...

  4. Android中WIFI开发总结(一)

    WIFI就是一种无线联网技术,常见的是使用无线路由器.那么在这个无线路由器的信号覆盖的范围内都可以采用WIFI连接的方式进行联网.如果无线路由器连接了一个ADSL线路或其他的联网线路,则又被称为&qu ...

  5. 【Android】Android中WIFI开发总结(二)

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://smallwoniu.blog.51cto.com/3911954/1338618 ...

  6. 【Android】Android中WIFI开发总结(一)

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://smallwoniu.blog.51cto.com/3911954/1334951 ...

  7. Android无线Wifi开发

    一.Wife的基础知识 WIFI就是一种无线联网技术,常见的是使用无线路由器.那么在这个无线路由器的信号覆盖的范围内都可以采用WIFI连接的方式进行联网.如果无线路由器连接了一个ADSL线路或其他的联 ...

  8. android之wifi开发

    WIFI就是一种无线联网技术,常见的是使用无线路由器.那么在这个无线路由器的信号覆盖的范围内都可以采用WIFI连接的方式进行联网.如果无线路由器连接了一个ADSL线路或其他的联网线路,则又被称为&qu ...

  9. android之wifi开发(一)

    WIFI就是一种无线联网技术,常见的是使用无线路由器.那么在这个无线路由器的信号覆盖的范围内都可以采用WIFI连接的方式进行联网.如果无线路由器连接了一个ADSL线路或其他的联网线路,则又被称为&qu ...

最新文章

  1. python恶搞表情包-用 Python 把你的朋友变成表情包
  2. git-svn 在ubuntu deepin(Linux debian系)下的安装与应用
  3. python笔试编程题_python_编程面试题
  4. python中pop(),popitem()的整理
  5. 没写client,想先测试server端怎么办?
  6. C++ primer 笔记(二)
  7. C语言中auto,register,extern,static【转】
  8. 测试python第二周_python第二周作业
  9. P,NP,NPC,NP-Hard,co-NP问题辨析
  10. arraychangekeycase php,浅谈php数组array_change_key_case() 函数和array_chunk()函数
  11. 爬虫练习:爬豆瓣读书的短评
  12. 企业应用大数据探索发展新路径
  13. 机器学习实验——回归预测算法
  14. 【Ad Hoc】贰 AODV 协议详解
  15. 怎么用静图做gif动图?三步教你轻松做动图
  16. 图片特效展示(鼠标移入移除特效)
  17. 我从华为身上学到的项目管理经验 -- 测试篇
  18. 服务器cpu占用过高一般是什么原因,如何解决服务器cpu使用率过高的問題
  19. 陆面生态水文模拟与多源遥感数据同化技术
  20. 亚马逊巴西站对中国商家正式开放试运营,如何快速提升销量

热门文章

  1. 处理大规模数据的基础知识
  2. ORACLE +win2003 群集手记
  3. rocksdb原理_rocksdb合并原理
  4. 如何打开mysql odbc数据源_mysql是如何配置ODBC数据源的方法
  5. Python3教程:functools模块的用法
  6. 秀一波多线程的操作技巧,又能Get新知识点了
  7. java计算机毕业设计HTML5“守护萌宠”网站设计与实现源码+mysql数据库+系统+lw文档+部署
  8. 综合课程设计作业——LOL英雄数据分析统计(个人)
  9. 负2次方计算机怎么算,3的负2次方怎么算呀
  10. 2k2实用球员_NBA2KOL2:五个位置中的实用类型球员,理查德森是新一代神器