1. 程式人生 > >【Android開發】wifi開關與wifi連線(密碼連線)

【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()  網路標識idwifi名稱改掉,會跟著變)

wifiInfo.getRssi()  當前無線網路的訊號強度指示器

wifiInfo.getSSID()  當前無線網路的名稱

wifiInfo.describeContents()  未知

注:

Int型別ipString型別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();

傳入要連線的wifiSSID(即wifi名稱,匹配得到則不用輸入密碼即可連線,匹配不到則要輸入密碼才能連線)

這裡需要注意的是:WifiConfiguration裡封裝的wifiSSID是包含雙引號的,而ScanResultSSID是不包含雙引號的,這裡進行遍歷比較時需要注意!

對於連線已經配置過的wifi,這裡遍歷的結果返回一個WifiConfiguration的物件,拿來實現連線;另外這裡的wifiManager已經存在了要連線的wifinetworkId,所以不用重新呼叫wifiManageraddNetwork方法,程式碼如下:

/**
 * 已有配置連結
 * 
 * @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);

注:這裡的typewifi的加密型別,加密型別檢視原始碼有

	/**
	 * 加密型別
	 * 
	 * @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;
}