在RK3188板卡上实现Wifi配置与连接,在网上搜索了一些资料了解到wifi连接流程,下面是从第一次刷机后的连接wifi流程
1、判断wifi是否启动如果没启动则打开wifi
2、扫描wifi根据要连接的wifi名称检索出想要的扫描结果
3、扫描结果判断该名称wifi的加密类型
4、根据wifi加密类型创建wifi配置
5、将wifi配置添加都wiifi配置列表,得到该配置的唯一ID;这部很重要
6、根据得到的配置ID进行连接wifi
先贴出自己实现的一个Wifi辅助类
package com.midea.test.factory.wifi;
import java.util.List;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.AuthAlgorithm;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.net.wifi.WifiManager;
public class WifiHelper {
public static final int SECURITY_NONE = 0;
public static final int SECURITY_WEP = 1;
public static final int SECURITY_PSK = 2; // WPA、WPA2、WPA_WPA2
public static final int SECURITY_EAP = 3;
public static void startScan(Context context){
WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
manager.startScan();
}
public static List<ScanResult> getScanResults(Context context){
WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
return manager.getScanResults();
}
public static boolean isWifiOpen(Context context){
WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
return manager.isWifiEnabled();
}
public static void setWifiEnabled(Context context,boolean isEnabled){
WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
manager.setWifiEnabled(isEnabled); //是否打开需监听广播 WIFI_STATE_CHANGED_ACTION
}
public static int updateWifiConfiguration(Context context,WifiConfiguration configuration){
WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
return manager.updateNetwork(configuration);
}
public static boolean isWifiConnected(Context context)
{
ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo[] networkInfos = connectivityManager.getAllNetworkInfo();
if(networkInfos == null){
return false;
}
for(int i =0; i < networkInfos.length; i ++){
if(networkInfos[i].getState()== NetworkInfo.State.CONNECTED){
return true;
}
}
return false ;
}
public static WifiConfiguration checkWifiConfiguration(Context context,String ssid){
WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
List<WifiConfiguration> configurations = manager.getConfiguredNetworks();
if(configurations == null){
return null;
}
for(WifiConfiguration configuration :configurations){
if(configuration.SSID.equals(ssid)){
return configuration;
}
}
return null;
}
public static int getSecurity(ScanResult result) {
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;
}
public static String convertToQuotedString(String string) {
return "\"" + string + "\"";
}
//from com.android.settings.wifi.WifiConfigController
/**
* 这里直接是阅读系统设置里面的wifi配置
* 其实这里可以阅读以下WifiConfiguration,里面关于wifi的加密参数
* @param accessPointSecurity
* @param ssid
* @param password
* @return
*/
public static WifiConfiguration getConfig(int accessPointSecurity, String ssid,
String password) {
WifiConfiguration config = new WifiConfiguration();
config.SSID = convertToQuotedString(ssid);
config.hiddenSSID = true;
switch (accessPointSecurity) {
case SECURITY_NONE:
config.allowedKeyManagement.set(KeyMgmt.NONE);
break;
case SECURITY_WEP:
config.allowedKeyManagement.set(KeyMgmt.NONE);
config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);
int length = password.length();
// WEP-40, WEP-104, and 256-bit WEP (WEP-232?)
if ((length == 10 || length == 26 || length == 58)
&& password.matches("[0-9A-Fa-f]*")) {
config.wepKeys[0] = password;
} else {
config.wepKeys[0] = '"' + password + '"';
}
break;
case SECURITY_PSK:
config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
if (password.length() != 0) {
if (password.matches("[0-9A-Fa-f]{64}")) {
config.preSharedKey = password;
} else {
config.preSharedKey = '"' + password + '"';
}
}
break;
case SECURITY_EAP:
//EAP暂时还没不完整
config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
break;
default:
return null;
}
return config;
}
public static int addWifiConfiguration(Context context,WifiConfiguration configuration){
WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
return manager.addNetwork(configuration);
}
public static void connectWifi(Context context,int networkId){
WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
manager.enableNetwork(networkId, true);
}
}
1、如果没打开Wifi就打开Wifi,然后在广播“WifiManager.WIFI_STATE_CHANGED_ACTION”去扫描wifi热点(当然这里不够严格,应该还要判断wifi状态是否可用);
如果wifi是打开状态就直接扫描,扫描wifi会触发“WifiManager.NETWORK_STATE_CHANGED_ACTION”广播,在这个广播里面获取WifiInfo后可以判断要连接的wifi名称是否存在,如果存在则WIFI是已经连接的。
2、启动扫描后不是立即返回扫描列表的,可以看看API解释
/**
* Request a scan for access points. Returns immediately. The availability
* of the results is made known later by means of an asynchronous event sent
* on completion of the scan.
* @return {@code true} if the operation succeeded, i.e., the scan was initiated
*/
public boolean startScan() {
try {
final WorkSource workSource = null;
mService.startScan(workSource);
return true;
} catch (RemoteException e) {
return false;
}
}
英语不好就用有道翻译一下Request a scan for access points. Returns immediately. The availability of the results is made knownlater by means of an
asynchronous event sent on completion of the scan.主要看到这个几个红字便可知道异步返回,需要监听广播“WifiManager.SCAN_RESULTS_AVAILABLE_ACTION”
3、扫描列表出来后需要或者要连接的wifi加密方式,以下是摘自系统设置的代码
public static int getSecurity(ScanResult result) {
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;
}
其实这里的PSK是包含WPA、WPA2、WPA_WPA2三种加密方式(可以阅读系统设置的WifiConfigController.java)
4、得到要连接wifi的加密方式后这时需创建wifi配置,代码如下也是摘自系统设置的
//from com.android.settings.wifi.WifiConfigController
/**
* 这里直接是阅读系统设置里面的wifi配置
* 其实这里可以阅读以下WifiConfiguration,里面关于wifi的加密参数
* @param accessPointSecurity
* @param ssid
* @param password
* @return
*/
public static WifiConfiguration getConfig(int accessPointSecurity, String ssid,
String password) {
WifiConfiguration config = new WifiConfiguration();
config.SSID = convertToQuotedString(ssid);
config.hiddenSSID = true;
switch (accessPointSecurity) {
case SECURITY_NONE:
config.allowedKeyManagement.set(KeyMgmt.NONE);
break;
case SECURITY_WEP:
config.allowedKeyManagement.set(KeyMgmt.NONE);
config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);
int length = password.length();
// WEP-40, WEP-104, and 256-bit WEP (WEP-232?)
if ((length == 10 || length == 26 || length == 58)
&& password.matches("[0-9A-Fa-f]*")) {
config.wepKeys[0] = password;
} else {
config.wepKeys[0] = '"' + password + '"';
}
break;
case SECURITY_PSK:
config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
if (password.length() != 0) {
if (password.matches("[0-9A-Fa-f]{64}")) {
config.preSharedKey = password;
} else {
config.preSharedKey = '"' + password + '"';
}
}
break;
case SECURITY_EAP:
//EAP暂时还没不完整
config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
break;
default:
return null;
}
return config;
}
5、配置好后需要添加到wifi配置列表得到配置的id
manager.addNetwork(configuration);
6、通过配置的ID提交连接,连接的过程也是异步的,需要监听广播“WifiManager.NETWORK_STATE_CHANGED_ACTION”,在这个广播里面获取WifiInfo后可以判断要连接的wifi名称是否存在,如果存在则WIFI是已经连接的。
以上只是大概的流程,还需严格控制。