一、最近开发wifi热点扫描功能,要判断当前连接的wifi热点是否需要密码。在网上搜索之后,发现有如下方法:
private static final int WIFI_NEED_PASSWORD = 0;
private static final int WIFI_NO_PASSWORD = 1;
private static final int WIFI_NOT_CONNECTED = 2;
public static final String WIFI_AUTH_OPEN = "";
public static final String WIFI_AUTH_ROAM = "[ESS]";
private static int checkWifiPassword(Context context) {
WifiInfo wifiInfo = null;
WifiManager mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
try {
mWifiManager.startScan();
// 得到当前连接的wifi热点的信息
wifiInfo = mWifiManager.getConnectionInfo();
} catch (SecurityException e) {
return WIFI_NEED_PASSWORD;
} catch (Exception ex) {
ex.printStackTrace();
}
if (wifiInfo == null) {
Log.i(TAG, "wifi not connected");
return WIFI_NOT_CONNECTED;
}
String ssid = wifiInfo.getSSID();
if (ssid == null) {
return WIFI_NOT_CONNECTED;
} else if (ssid.length() <= 2) {
return WIFI_NOT_CONNECTED;
}
if (ssid.startsWith("\"") && ssid.endsWith("\"")) {
ssid = ssid.substring(1, ssid.length() - 1);
}
List<ScanResult> mWifiList = null;
try {
// 得到扫描结果
mWifiList = mWifiManager.getScanResults();
} catch (SecurityException e) {
return WIFI_NEED_PASSWORD;
} catch (Exception e) {
e.printStackTrace();
}
if (mWifiList != null && mWifiList.size() > 0) {
try {
for (ScanResult sr : mWifiList) {
if (sr.SSID.equals(ssid) && sr.BSSID.equals(wifiInfo.getBSSID())) {
if (sr.capabilities != null) {
String capabilities = sr.capabilities.trim();
if (capabilities != null && (capabilities.equals(WIFI_AUTH_OPEN) || capabilities.equals(WIFI_AUTH_ROAM))) {
return WIFI_NO_PASSWORD;
}
}
}
}
} catch (Throwable e) {
return WIFI_NEED_PASSWORD;
}
}
return WIFI_NEED_PASSWORD;
}
AndroidManifest.xml添加如下权限
<!--wifi扫描需要此权限-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
上述方法的确可以通过capabilities来判断wifi是否需要密码,但是测试过程中发现:有些手机如果在settings页面把“定位”功能关闭,则无法获取到扫描结果,WifiManager.getScanResults() 总是返回空。为了解决这个问题,我尝试着用其它方法来判断,后来证明可以用WifiConfigration来代替capabilities进行判断。
二、ScanResult 、 WifiConfiguration、WifiInfo的简介
(1) ScanResult:主要是通过wifi 硬件的扫描来获取一些周边的wifi 热点的信息。在我们进行wifi 搜索的时候,一般会搜到这些信息,首先是接入点名字、接入点信息的强弱、还有接入点使用的安全模式,是WPA、WPE。打开这个类,我们可以看到以下几个信息
BSSID 接入点的地址,这里主要是指小范围几个无线设备相连接所获取的地址,比如说两台笔记本通过无线网卡进行连接,双方的无线网卡分配的地址。
SSID 网络的名字,当我们搜索一个网络时,就是靠这个来区分每个不同的网络接入点。
Capabilities 网络接入的性能,这里主要是来判断网络的加密方式等。
Frequency 频率,每一个频道交互的MHz 数。
Level 等级,主要来判断网络连接的优先数。
(2) WifiConfiguration: 在我们连通一个wifi 接入点的时候,需要获取到的一些信息:
1. WifiConfiguration.AuthAlgorthm 设置加密方法。
可选参数:LEAP只用于leap,
OPEN 被wpa/wpa2需要,
SHARED需要一个静态的wep key
2. WifiConfiguration.GroupCipher 使用使用GroupCipher 的方法来进行加密。
可选参数:CCMP,TKIP,WEP104,WEP40
3. WifiConfiguration.KeyMgmt 键管理机制(keymanagerment),使用KeyMgmt 进行.
可选参数IEEE8021X,NONE,WPA_EAP,WPA_PSK
4. WifiConfiguration.PairwiseCipher 设置加密方式。
可选参数 CCMP,NONE,TKIP
5. WifiConfiguration.Protocol 设置使用哪一种协议进行加密。
可选参数 RSN,WPA,
6. wifiConfiguration.Status 设置当前网络的状态。
可选参数CURRENT,DISABLED,ENABLED,
(3) WifiInfo :在我们的wifi 已经连通了以后,可以通过这个类获得一些已经连通的wifi 连接的信息获取当前链接的信息,这里简单介绍一下这里的方法:
getBSSID() 获取BSSID
getDetailedStateOf() 获取客户端的连通性
getHiddenSSID() 获得SSID 是否被隐藏
getIpAddress() 获取IP 地址
getLinkSpeed() 获得连接的速度
getMacAddress() 获得Mac 地址
getRssi() 获得802.11n 网络的信号
getSSID() 获得SSID
getSupplicanState() 返回具体客户端状态的信息
三、使用WifiConfiguration来判断wifi是否需要密码,此方法不需要扫描wifi热点,即使在settings页面把“定位”功能关闭,仍能正常工作。具体实现如下:
/**
* 利用WifiConfiguration.KeyMgmt的管理机制,来判断当前wifi是否需要连接密码
* @param wifiManager
* @return true:需要密码连接,false:不需要密码连接
*/
public static boolean checkIsCurrentWifiHasPassword(String currentWifiSSID, ) {
try {
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
// 得到当前连接的wifi热点的信息
WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
// 得到当前WifiConfiguration列表,此列表包含所有已经连过的wifi的热点信息,未连过的热点不包含在此表中
List<WifiConfiguration> wifiConfiguration = wifiManager.getConfiguredNetworks();
String currentSSID = wifiInfo.getSSID();
if (currentSSID != null && currentSSID.length() > 2) {
if (currentSSID.startsWith("\"") && currentSSID.endsWith("\"")) {
currentSSID = currentSSID.substring(1, currentSSID.length() - 1);
}
if (wifiConfiguration != null && wifiConfiguration.size() > 0) {
for (WifiConfiguration configuration : wifiConfiguration) {
if (configuration != null && configuration.status == WifiConfiguration.Status.CURRENT) {
String ssid = null;
if (!TextUtils.isEmpty(configuration.SSID)) {
ssid = configuration.SSID;
if (configuration.SSID.startsWith("\"") && configuration.SSID.endsWith("\"")) {
ssid = configuration.SSID.substring(1, configuration.SSID.length() - 1);
}
}
if (TextUtils.isEmpty(currentSSID) || currentSSID.equalsIgnoreCase(ssid)) {
//KeyMgmt.NONE表示无需密码
return (!configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE));
}
}
}
}
} catch (Exception e) {
//do nothing
}
//默认为需要连接密码
return true;
}