【Android開發】wifi開關與wifi連線(密碼連線)
過放蕩不羈的生活,容易得像順水推舟,但是要結識良朋益友,卻難如登天。—— 巴爾扎克
本文demo來自網路,找了好久找到的,後面自己做了些許修改,這裡對原始碼解析,愧於忘記哪裡出來了,感謝作者!
接下來就記錄一下wifi開發的一些學習心得,這邊先看幾張效果圖吧!
本文大綱:
1. 當前wifi連線資訊
2. 開關wifi(自動連線已經配置過的wifi)
3. Wifi掃描,選擇要連線的wifi,使用密碼連線
內容:
1. 當前wifi連線資訊
首先先加入這個demo用到的幾個許可權
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" > </uses-permission> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" > </uses-permission> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" > </uses-permission> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" > </uses-permission>
Wifi相關操作這裡demo建立了WifiAdmin這個類,作為業務類,這裡首先我們要獲取當前wifi的狀態
獲取wifi連線狀態使用:int android.net.wifi.WifiManager.getWifiState()
Wifi狀態有:
獲取當前wifi的連線資訊使用:
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
列印wifiInfo主要方法的資訊:
wifiInfo.getBSSID() 得到無線的Mac
wifiInfo.getHiddenSSID() 未知(true if this network does not broadcast its SSID, so an SSID-specific probe request must be used for scans.)
wifiInfo.getIpAddress() int型別ip地址,需要轉成String
wifiInfo.getLinkSpeed() 連線速度,單位Mbps
wifiInfo.getNetworkId() 網路標識id(wifi名稱改掉,會跟著變)
wifiInfo.getRssi() 當前無線網路的訊號強度指示器
wifiInfo.getSSID() 當前無線網路的名稱
wifiInfo.describeContents() 未知
注:
Int型別ip轉String型別ip程式碼:
public String ipIntToString(int ip) {
try {
byte[] bytes = new byte[4];
bytes[0] = (byte) (0xff & ip);
bytes[1] = (byte) ((0xff00 & ip) >> 8);
bytes[2] = (byte) ((0xff0000 & ip) >> 16);
bytes[3] = (byte) ((0xff000000 & ip) >> 24);
return Inet4Address.getByAddress(bytes).getHostAddress();
} catch (Exception e) {
return "";
}
}
2. 開關wifi
開啟關閉wifi使用wifiManager.setWifiEnabled()的方法,開啟關閉前,先要判斷wifi的狀態,使用isWifiEnabled()方法。
開啟wifi :
/**
* 開啟wifi功能
*
* @return true or false
*/
public boolean OpenWifi() {
boolean bRet = true;
if (!wifiManager.isWifiEnabled()) {
bRet = wifiManager.setWifiEnabled(true);
}
return bRet;
}
關閉wifi :
/**
* 關閉wifi
*
* @return
*/
public boolean closeWifi() {
if (!wifiManager.isWifiEnabled()) {
return true;
} else {
return wifiManager.setWifiEnabled(false);
}
}
注:開關wifi,系統會自動識別儲存過密碼的wifi去連線
3. Wifi掃描,選擇要連線的wifi,使用密碼連線
Wifi掃描結果的列表使用List<ScanResult> 儲存
掃描步驟:
wifiManager.startScan(); //開啟掃描
scanResultList = wifiManager.getScanResults(); // 掃描返回結果列表
列印一個ScanResult的資料
資料說明:
ScanResult:
BSSID:fc:e3:3c:4e:f0:34
capabilities:[WPA-PSK-TKIP][ESS] 加密方案
frequency:2412
level:-48 訊號的強弱標誌(單位dBm分貝毫伏)
SSID:ChinaNet-kgdp wifi名稱
timestamp:238673772811
describeContents():0
level根據數值可以分為5個等級的訊號強弱:
Level>-50 訊號最強4格
-50<Level<-65 訊號3格
-65<Level<-75 訊號2格
-75<Level<-90 訊號1格
-90<Level 訊號0格
Ps: 也可以做更細的劃分
選擇wifi進行連線,這裡分為連線已經配置過的wifi以及未配置過的wifi
A.連線已經配置過wifi
檢查是否已經配置過該wifi,通過WifiManager獲取已經配置的wifi列表
List<WifiConfiguration> existingConfigs = wifiManager.getConfiguredNetworks();
傳入要連線的wifi的SSID(即wifi名稱,匹配得到則不用輸入密碼即可連線,匹配不到則要輸入密碼才能連線)
這裡需要注意的是:WifiConfiguration裡封裝的wifi的SSID是包含雙引號的,而ScanResult的SSID是不包含雙引號的,這裡進行遍歷比較時需要注意!
對於連線已經配置過的wifi,這裡遍歷的結果返回一個WifiConfiguration的物件,拿來實現連線;另外這裡的wifiManager已經存在了要連線的wifi的networkId,所以不用重新呼叫wifiManager的addNetwork方法,程式碼如下:
/**
* 已有配置連結
*
* @param wf
* @return
*/
public boolean Connect(WifiConfiguration wf) {
if (!this.OpenWifi()) {
return false;
}
// 狀態變成WIFI_STATE_ENABLED的時候才能執行下面的語句,即當狀態為WIFI_STATE_ENABLING時,讓程式在while裡面跑
while (wifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLING) {
try {
// 為了避免程式一直while迴圈,讓它睡個100毫秒在檢測……
Thread.currentThread();
Thread.sleep(100);
} catch (InterruptedException ie) {
}
}
boolean bRet = wifiManager.enableNetwork(wf.networkId, true);
wifiManager.saveConfiguration();
return bRet;
}
B.連線未配置的wifi
輸入密碼,根據密碼建立一個配置資訊類
WifiConfiguration wifiConfig = this.CreateWifiInfo(SSID, Password, Type);
注:這裡的type是wifi的加密型別,加密型別檢視原始碼有
/**
* 加密型別
*
* @author Administrator
*
*/
public enum WifiCipherType {
WIFICIPHER_WEP, WIFICIPHER_WPA, WIFICIPHER_NOPASS, WIFICIPHER_INVALID
}
一般使用WIFICIPHER_WPA這種加密方式,還有web以及無密碼的方式。
然後呼叫addNetwork把配置資訊加入WifiManager(這裡返回networkId ),加入後預設是DISABLED(即斷開狀態的),還要再呼叫WifiManager.enableNetwork(int netId, boolean disableOthers)去啟用,這裡傳入引數addNetwork方法返回的networkId ,就能啟動連線了,布林值傳入true,關閉別的網路,程式碼:
/**
* 無配置記錄連結方式
*
* @param SSID
* @param Password
* @param Type
* @return true or false
*/
public boolean Connect(String SSID, String Password, WifiCipherType Type) {
if (!this.OpenWifi()) {
return false;
}
// 狀態變成WIFI_STATE_ENABLED的時候才能執行下面的語句
while (wifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLING) {
try {
// 為了避免程式一直while迴圈,讓它睡個100毫秒在檢測……
Thread.currentThread();
Thread.sleep(100);
} catch (InterruptedException ie) {
}
}
WifiConfiguration wifiConfig = this
.CreateWifiInfo(SSID, Password, Type);
int netID = wifiManager.addNetwork(wifiConfig);
boolean bRet = wifiManager.enableNetwork(netID, true);
wifiManager.saveConfiguration();
return bRet;
}