在上一篇中我们介绍了WiFi热点的创建和关闭,如果你还没阅读过,建议先阅读上一篇文章Android WiFi开发教程(一)——WiFi热点的创建与关闭。 本章节主要继续介绍WiFi的搜索和连接。

WiFi的搜索

  /* 搜索wifi热点*/private void search() {if (!wifiManager.isWifiEnabled()) {//开启wifiwifiManager.setWifiEnabled(true);}wifiManager.startScan();}

我们在开始搜索WiFi之前确保当前WiFi功能是处于开启状态。如果未开启,通过调用WifiManager的setWifiEnabled(boolean enable)去开启。之后调用startScan()就开始扫描附近的WiFi了。而获取扫描的结果我们就需要创建一个广播接收者来处理。

private BroadcastReceiver receiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {final String action = intent.getAction();if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {// wifi已成功扫描到可用wifi。List<ScanResult> scanResults = wifiManager.getScanResults();wifiListAdapter.clear();wifiListAdapter.addAll(scanResults);} };

系统在扫描结束后,会发出WifiManager.SCAN_RESULTS_AVAILABLE_ACTION的广播,当我们的接收者接收到这个广播的时候,通过WifiManager的getScanResults()就能获取到扫描结果的集合了。ScanResult保存着每一个WiFi的信息。这里我将这个集合设置到Adapter中,并在列表中展示出来。下面是Apater中主要的代码:

 @Overridepublic View getView(int position, View convertView, ViewGroup parent) {if (convertView == null) {convertView = mInflater.inflate(mResource, parent, false);}TextView name = (TextView) convertView.findViewById(R.id.wifi_name);TextView signl = (TextView) convertView.findViewById(R.id.wifi_signal);ScanResult scanResult = getItem(position);name.setText(scanResult.SSID);int level = scanResult.level;if (level <= 0 && level >= -50) {signl.setText("信号很好");} else if (level < -50 && level >= -70) {signl.setText("信号较好");} else if (level < -70 && level >= -80) {signl.setText("信号一般");} else if (level < -80 && level >= -100) {signl.setText("信号较差");} else {signl.setText("信号很差");}return convertView;}

可以看出列表展示的数据也是比较简单,只有WiFi的名称和信号强度,这两个数据也是平时用得比较多的。获取到扫描结果后,我们就可以处理连接的逻辑了。

WiFi的连接

WiFi的连接相当于搜索就要复杂一些。首先给列表项设置点击事件,获取对应的ScanResult。

   listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {wifiManager.disconnect();final ScanResult scanResult = wifiListAdapter.getItem(position);String capabilities = scanResult.capabilities;int type = WIFICIPHER_WPA;if (!TextUtils.isEmpty(capabilities)) {if (capabilities.contains("WPA") || capabilities.contains("wpa")) {type = WIFICIPHER_WPA;} else if (capabilities.contains("WEP") || capabilities.contains("wep")) {type = WIFICIPHER_WEP;} else {type = WIFICIPHER_NOPASS;}}config = isExsits(scanResult.SSID);});

获取到ScanResult后我们通过他的capabilities属性判断WiFi的加密方式。接着通过isExsits(String SSID)方法判断系统是否保存着当前WiFi的信息。

private WifiConfiguration isExsits(String SSID) {List<WifiConfiguration> existingConfigs = wifiManager.getConfiguredNetworks();for (WifiConfiguration existingConfig : existingConfigs) {if (existingConfig.SSID.equals("\"" + SSID + "\"")) {return existingConfig;}}return null;}

如果之前连接过,则返回WiFi的配置信息,否则返回空对象。然后接着处理连接的逻辑

if (config == null) {if (type != WIFICIPHER_NOPASS) {//需要密码final EditText editText = new EditText(MainActivity.this);final int finalType = type;new AlertDialog.Builder(MainActivity.this).setTitle("请输入Wifi密码").setIcon(android.R.drawable.ic_dialog_info).setView(editText).setPositiveButton("确定", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {Log.w("AAA", "editText.getText():" + editText.getText());config = createWifiInfo(scanResult.SSID, editText.getText().toString(), finalType);connect(config);}}).setNegativeButton("取消", null).show();return;} else {config = createWifiInfo(scanResult.SSID, "", type);connect(config);}} else {connect(config);}

当没有获取到所要连接WiFi的配置信息时,我们就需要用到前面获取到的加密方式判断是否需要输入密码。如果加密方式为WAP或WEP时,则弹出提示框提示用户输入WiFi密码。用户输入密码后再调用connect(WifiConfiguration config)方法

如果可以获取到所要连接WiFi的配置信息,则直接调用connect(WifiConfiguration config)。

private void connect(WifiConfiguration config) {int wcgID = wifiManager.addNetwork(config);wifiManager.enableNetwork(wcgID, true);}

直接调用WifiManger的addNetwork方法,将配置信息传进去后,会创建一个新的网络描述的身份并返回回来,如果返回来是-1,则表示创建失败。获取到身份后,调用enableNetwork方法就能开始连接WiFi了。到了这里,我们连接部分就完成了一半,接下来需要继续处理WiFi连接过程中返回来的状态。这里同样我们是需要用到广播接收者来处理。

if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);if (info.getState().equals(NetworkInfo.State.DISCONNECTED)) {text_state.setText("连接已断开");} else if (info.getState().equals(NetworkInfo.State.CONNECTED)) {WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);final WifiInfo wifiInfo = wifiManager.getConnectionInfo();text_state.setText("已连接到网络:" + wifiInfo.getSSID());}} else {NetworkInfo.DetailedState state = info.getDetailedState();if (state == state.CONNECTING) {text_state.setText("连接中...");} else if (state == state.AUTHENTICATING) {text_state.setText("正在验证身份信息...");} else if (state == state.OBTAINING_IPADDR) {text_state.setText("正在获取IP地址...");} else if (state == state.FAILED) {text_state.setText("连接失败");}}}

上面是广播接收者中的关键代码。WiFi在连接的过程中系统会发出WifiManager.NETWORK_STATE_CHANGED_ACTION的广播,当接收者接收到这条广播时,获取NetworkInfo的state来判断当前的连接状态。状态值分别代表如下

NetworkInfo.State.DISCONNECTED //连接已断开
NetworkInfo.State.CONNECTED //已成功连接

除了这两个状态之外,这里还判断了其他状态

NetworkInfo.DetailedState state = info.getDetailedState();if (state == state.CONNECTING) {text_state.setText("连接中...");} else if (state == state.AUTHENTICATING) {text_state.setText("正在验证身份信息...");} else if (state == state.OBTAINING_IPADDR) {text_state.setText("正在获取IP地址...");} else if (state == state.FAILED) {text_state.setText("连接失败");}

DetailedState中包含了很多连接状态的信息,这里只对部分状态进行处理,其他状态值解析具体如下

IDLE:空闲
SCANNING:正在扫描
CONNECTING:连接中
AUTHENTICATING:正在进行身份验证
OBTAINING_IPADDR:正在获取Ip地址
CONNECTED:已连接
SUSPENDED:已暂停
DISCONNECTING:正在断开连接
DISCONNECTED:已断开
FAILED:失败
BLOCKED:已阻止
VERIFYING_POOR_LINK:暂时关闭(网络状况不佳)
CAPTIVE_PORTAL_CHECK:判断是否需要浏览器二次登录

到这里WiFi连接的逻辑就处理完成了,相对于WiFi热点的创建和关闭,搜索和连接确实要复杂一些。欢迎阅读下一篇Android WiFi开发教程(三)——WiFi热点数据传输

Android WiFi开发教程(二)——WiFi的搜索和连接相关推荐

  1. Android简明开发教程二十一:访问Internet 绘制在线地图

    在例子Android简明开发教程十七:Dialog 显示图像 中我们留了一个例子DrawMap()没有实现,这个例子显示在线地图,目前大部分地图服务器都是将地图以图片存储以提高响应速度. 一般大小为2 ...

  2. Android 日历开发教程[二]

    一.创建 Android Project 在新建对话框中输入 App 属性,SDK版本全部选最新的,不作版本兼容.主题选择 Holo Dark. 下一步,使用默认设置 下一步,使用默认设置 下一步,使 ...

  3. Android蓝牙开发教程(二)——连接蓝牙设备

    在上一篇中已经介绍如何搜索附近可连接的蓝牙设备,如果你还没阅读过,建议先看看上一篇文章Android蓝牙开发教程(一)--搜索蓝牙设备 获取到设备后就可以开始处理蓝牙设备之间的连接. 在上一篇教程中我 ...

  4. Android WiFi开发教程(三)——WiFi热点数据传输

    在上一篇文章中介绍了WiFi的搜索和连接,如果你还没阅读过,建议先阅读上一篇Android WiFi开发教程(二)--WiFi的搜索和连接.本篇接着简单介绍手机上如何通过WiFi热点进行数据传输. 跟 ...

  5. Android WiFi开发教程

    Android WiFi开发教程(一)--WiFi热点的创建与关闭 相对于BlueTooth,WiFi是当今使用最广的一种无线网络传输技术, 几乎所有智能手机.平板电脑和笔记本电脑都支持Wi-Fi上网 ...

  6. Android WiFi开发 (二)分享Wifi热点

    Android WiFi开发 (二)Wifi热点 标签: wi-fiandroid热点安全 2016-03-07 13:08  11415人阅读  评论(29)  收藏  举报   分类: Andro ...

  7. MIP开发教程(二) 使用MIP-CLI工具调试MIP网页

    初始化 MIP 配置 新建一个 MIP 网页 编写 MIP 网页代码 校验 MIP 网页 调试 MIP 网页 1. 初始化 MIP 配置 首先在html目录下进行初始化 MIP 配置: $ mip i ...

  8. Android视频开发基础(二)

    Android视频开发基础(二) https://blog.csdn.net/goodlixueyong/article/details/62447452 前一篇文章详细介绍了视频的一些基本概念,这些 ...

  9. Android游戏开发教程汇总

    Android游戏开发教程汇总 把最近搜集到的Android游戏开发教程列出来,希望对大家有用. 1.Android2.0游戏开发实战宝典源代码,当然可能大家已经把书也买回家啦. 2.Pro.Andr ...

最新文章

  1. sqlplusw下登录sys账户
  2. 网络工程师,不需要学Linux?
  3. 中科视拓开源SeetaFace2
  4. file.php https,使用HTTPS链接和php方法(file_get_contents,getimagesize)
  5. flask bootstrap ajax,使用Flask集成bootstrap的方法
  6. android 7.0 按钮崩溃,Android 7.0调用相机崩溃详解及解决办法
  7. 怎么删除已经安装的mysql_怎么样删除已经安装的mysql | wdlinux致力于Linux服务器架构,性能优化.免费CDN加速系统,免费智能DNS解析,负载均衡,集群分流...
  8. LINQ-to-SQL那点事~LINQ-to-SQL中的并发冲突与应对
  9. linux系统环境与文件权限
  10. git如何撤销已经push到远程仓库的代码提交
  11. RAC安装时,报The specified nodes are not clusterable 的解决方法
  12. HttpClient的简单使用--HttpGET和HttpPost
  13. 微信小程序商城模板平台分享
  14. MD5加密算法(python)
  15. 不精确微分/不完整微分(Inexact differential/Imperfect differential)
  16. 李建忠「设计模式」笔记
  17. hp扫描无法选择发送到计算机,HP Officejet Pro 8600打印机无法使用扫描到计算机的功能...
  18. 【CUDA 基础】3.4 避免分支分化
  19. vue npm install --save-dev css-loader出现的错误
  20. JQuery获取父,子,兄弟节点

热门文章

  1. 作为一个计算机学生该怎样度过大学生活
  2. 林清玄家属致读者信:人生难得,好好修行
  3. java调用.so方法
  4. idea类中左侧出现√的解决方法
  5. 外贸分享:多哥市场开发攻略
  6. 在kernel2.4.18下的s3c2410 AD驱动
  7. vscode中为golang开发环境配置代理goproxy
  8. html5鼠标滚轮事件mousewheel使用
  9. Android屏幕旋转设置
  10. UWB-DW1000初始化、发送和接收详解(一)