前言
在Android應(yīng)用層的開發(fā)中,使用到wifi相關(guān)知識點(diǎn)的地方并不多,所以之前對wifi開發(fā)并不熟悉,最近接到的兩個硬件項目都有用到wifi并且知識點(diǎn)越來越深入,所以有必要記一下筆記,做一些注釋。
基本使用
1.權(quán)限
Android中要使用系統(tǒng)功能一般都要申請權(quán)限,在6.0上可能還要手動申請權(quán)限,這里wifi需要的權(quán)限有
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> // 需要系統(tǒng)權(quán)限 [定位權(quán)限]
其中在6.0以上設(shè)備,定位權(quán)限需要主動申請,并且如果要獲取掃描wifi列表需要打開系統(tǒng)的定位開關(guān)。
2. WiFi相關(guān)API
ScanResult類用于存放wifi掃描結(jié)果信息,包含ssid(wifi名稱), bssid(網(wǎng)絡(luò)接入點(diǎn)地址),capabilities(加密類型),frequency(傳輸頻率),level(信號強(qiáng)度)等。這里的解釋并不太標(biāo)準(zhǔn),但是對應(yīng)功能很形象,如果你要了解更多,可以去具體的查閱資料。
WifiConfiguration類用于存放wifi的配置信息。包括wifi的密碼,加密類型,網(wǎng)絡(luò)id(用于連接wifi)等。他的幾個子類分別對應(yīng)秘鑰加密方式,安全協(xié)議等,這些在設(shè)置wifi配置的時候會被用到
wifiinfo類用來描述wifi屬性和連接狀態(tài)。暴露了一些方法給開發(fā)者調(diào)用。getBSSID(), getMacAddress(), getIpAddress(),getSSID()等
WifiManager類是framework層暴露的api,用來管理wifi。通過調(diào)用 Context.getSystemService(Context.WIFI_SERVICE)可以得到類的實例。通過他可以得到:1.已經(jīng)配置的網(wǎng)絡(luò)列表。2.當(dāng)前連接的wifi。3.掃描到的wifi。4.以及一些常量表示廣播的意圖等
3. wifi狀態(tài)及開關(guān)
/**
* 判斷wifi是否打開
* <p>需添加權(quán)限 {@code <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>}</p>
*
* @return {@code true}: 是<br>{@code false}: 否
*/
public static boolean getWifiEnabled() {
@SuppressLint("WifiManagerLeak")
WifiManager wifiManager = (WifiManager) Utils.getApp().getSystemService(Context.WIFI_SERVICE);
return wifiManager.isWifiEnabled();
}
/**
* 打開或關(guān)閉wifi
* <p>需添加權(quán)限 {@code <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>}</p>
*
* @param enabled {@code true}: 打開<br>{@code false}: 關(guān)閉
*/
public static void setWifiEnabled(final boolean enabled) {
@SuppressLint("WifiManagerLeak")
WifiManager wifiManager = (WifiManager) Utils.getApp().getSystemService(Context.WIFI_SERVICE);
if (enabled) {
if (!wifiManager.isWifiEnabled()) {
wifiManager.setWifiEnabled(true);
}
} else {
if (wifiManager.isWifiEnabled()) {
wifiManager.setWifiEnabled(false);
}
}
}
4. 掃描wifi
/**
*
* 獲取WIFI列表
* <p>需要權(quán)限{@code <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>}</p>
* <p>注意Android6.0上需要主動申請定位權(quán)限,并且打開定位開關(guān)</p>
*
* @param context 上下文
* @return wifi列表
*/
public static List<ScanResult> getWifiList(Context context) {
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
List<ScanResult> scanResults = wm.getScanResults();
Collections.sort(scanResults, new Comparator<ScanResult>() {
@Override
public int compare(ScanResult scanResult1, ScanResult scanResult2) {
return scanResult2.level - scanResult1.level;
}
});
return scanResultsCopy;
}
/**
* 獲取當(dāng)前鏈接的WiFi信息
*
* @param context 上下文
* @return 當(dāng)前wifi數(shù)據(jù)
*/
public static WifiInfo getCurrentWifi (Context context) {
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
return wm.getConnectionInfo();
}
public static String getWifiEncryptTypeStr (String capabilitie) {
if (TextUtils.isEmpty(capabilitie)) return null;
String encryptType;
if (capabilitie.contains("WPA") && capabilitie.contains("WPA2")) {
encryptType = "WPA/WPA2 PSK";
} else if (capabilitie.contains("WPA2")) {
encryptType = "WPA2 PSK";
} else if (capabilitie.contains("WPA")) {
encryptType = "WPA PSK";
} else if (capabilitie.contains("WEP")) {
encryptType = "WEP";
} else {
encryptType = "NONE";
}
return encryptType;
}
/**
* wifi加密方式有5種
* 0 - WPA/WPA2 PSK
* 1 - WPA2 PSK
* 2 - WPA PSK
* 3 - WEP
* 4 - NONE
* @param capabilitie
* @return
*/
public static int getWifiEncryptType (String capabilitie) {
if (TextUtils.isEmpty(capabilitie)) return -1;
int encryptType;
if (capabilitie.contains("WPA") && capabilitie.contains("WPA2")) {
encryptType = 0;
} else if (capabilitie.contains("WPA2")) {
encryptType = 1;
} else if (capabilitie.contains("WPA")) {
encryptType = 2;
} else if (capabilitie.contains("WEP")) {
encryptType = 3;
} else {
encryptType = 4;
}
return encryptType;
}
5. 連接wifi
/**
* @des 連接已經(jīng)保存過配置的wifi
* @param context
* @param ssid
*/
public static void connectWifi (Context context, String ssid) {
Log.d(TAG, "connectWifi: 去連接wifi: " + ssid);
if (!getWifiEnabled()) return;
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiConfiguration wc = new WifiConfiguration();
wc.SSID = "\"" + ssid + "\"";
WifiConfiguration configuration = getWifiConfig(context, ssid);
if (configuration != null) {
wm.enableNetwork(configuration.networkId, true);
}
}
/**
* @des 連接沒有配置過的wifi
* @param context
* @param ssid
* @param password
* @param encryptType
*/
public static void connectWifi (Context context, String ssid, String password, int encryptType) {
Log.d(TAG, "connectWifi: 去連接wifi: " + ssid);
if (!getWifiEnabled()) return;
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiConfiguration wc = new WifiConfiguration();
wc.allowedAuthAlgorithms.clear();
wc.allowedGroupCiphers.clear();
wc.allowedKeyManagement.clear();
wc.allowedPairwiseCiphers.clear();
wc.allowedProtocols.clear();
wc.SSID = "\"" + ssid + "\"";
WifiConfiguration configuration = getWifiConfig(context, ssid);
if (configuration != null) {
wm.removeNetwork(configuration.networkId);
}
switch (encryptType) {
case 4://不加密
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
break;
case 3://wep加密
wc.hiddenSSID = true;
wc.wepKeys[0] = "\"" + password +"\"";
wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
break;
case 0: //wpa/wap2加密
case 1: //wpa2加密
case 2: //wpa加密
wc.preSharedKey = "\"" + password + "\"";
wc.hiddenSSID = true;
wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wc.status = WifiConfiguration.Status.ENABLED;
break;
}
int network = wm.addNetwork(wc);
wm.enableNetwork(network, true);
}
public static void disConnectWifi (Context context, int networkId) {
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
wm.disableNetwork(networkId);
wm.disconnect();
}
6. 獲取和清除WIFI配置
/**
* @des 清除wifi配置信息
* @param context
* @param ssid
*/
public static void clearWifiInfo(Context context, String ssid) {
Log.d(TAG, "clearWifiInfo: 清除WIFI配置信息: " + ssid);
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
String newSSID = "\"" + ssid + "\"";
if (!(ssid.startsWith("\"") && ssid.endsWith("\""))) {
newSSID = "\"" + ssid + "\"";
} else {
newSSID = ssid;
}
WifiConfiguration configuration = getWifiConfig(context, newSSID);
configuration.allowedAuthAlgorithms.clear();
configuration.allowedGroupCiphers.clear();
configuration.allowedKeyManagement.clear();
configuration.allowedPairwiseCiphers.clear();
configuration.allowedProtocols.clear();
if (configuration != null) {
wm.removeNetwork(configuration.networkId);
wm.saveConfiguration();
}
}
public static WifiConfiguration getWifiConfig (Context context, String ssid) {
Log.d(TAG, "getWifiConfig: 獲取wifi配置信息: " + ssid);
if (TextUtils.isEmpty(ssid)) return null;
String newSSID;
if (!(ssid.startsWith("\"") && ssid.endsWith("\""))) {
newSSID = "\"" + ssid + "\"";
} else {
newSSID = ssid;
}
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
List<WifiConfiguration> configuredNetworks = wm.getConfiguredNetworks();
for (WifiConfiguration configuration : configuredNetworks) {
if (newSSID.equalsIgnoreCase(configuration.SSID)) {
return configuration;
}
}
return null;
}