Android WiFi开发教程(二)——WiFi的搜索和连接
2017-09-19 15:49
363 查看
在上一篇中我们介绍了WiFi热点的创建和关闭,如果你还没阅读过,建议先阅读上一篇文章Android WiFi开发教程(一)——WiFi热点的创建与关闭。 本章节主要继续介绍WiFi的搜索和连接。
WiFi的搜索
/* 搜索wifi热点 */ private void search() { if (!wifiManager.isWifiEnabled()) { //开启wifi wifiManager.setWifiEnabled(true); } wifiManager.startScan(); }
我们在开始搜索WiFi之前确保当前WiFi功能是处于开启状态。如果未开启,通过调用WifiManager的setWifiEnabled(boolean enable)去开启。之后调用startScan()就开始扫描附近的WiFi了。而获取扫描的结果我们就需要创建一个广播接收者来处理。
private BroadcastReceiver receiver = new BroadcastReceiver() { @Override public 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中主要的代码:
@Override public 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() { @Override public 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() { @Override public 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的搜索和连接
- android开发-wifi连接eclipse调试,拜拜USB
- android开发教程之ubuntu使用adb连接小米2的步骤和adb调试方法
- Android开发人员有福了---wifi连接调试
- android wifi开发 连接wifi 创建AP
- android WIFI连接开发
- android WIFI连接开发
- Android开发之Wifi基础教程
- android wifi连接开发实例
- Android开发之判断网络(wifi、3G)是否连接
- android wifi连接开发
- 自用连接:android经典教程,软件开发,项目管理,论坛链接,连接link
- android开发连接wifi addNetwork 返回-1
- WiFi 网络操作(一)-- MarsChen Android 开发教程学习笔记
- Android开发视频教程之二十三(WiFi网络操作 一)
- Android 设置wifi连接应用开发
- Android 搜索附近wifi并连接
- android开发-wifi连接eclipse开发调试环境
- android wifi连接开发实例
- Android开发心得-系统休眠时WIFI连接断开的解决办法