1. 程式人生 > >Android開發-WIFI實現

Android開發-WIFI實現

wifi的基本狀態

Android的官方文件中定義瞭如下五種WIFI狀態

WIFI_STATE_DISABLING  WIFI網絡卡正在關閉 0

WIFI_STATE_DISABLED   WIFI網絡卡不可用 1

WIFI_STATE_ENABLING    WIFI網絡卡正在開啟 2

WIFI_STATE_ENABLED     WIFI網絡卡可用 3

WIFI_STATE_UNKNOWN    WIFI網絡卡狀態不可知 4

如何操作WIFI

要操作WIFI裝置,就需要使用Context.getSystemService(Context.WIFI_SERVICE)來獲取WifiManager

物件,並通過這個物件來管理我們的WIFI裝置

如果要想得到周圍的WIFI熱點列表,可以使用WifiManager.getScanResults()返回一個ScanResult列表

這裡列了很多,但是大致可以分為四個主要的類:ScanResultwifiConfigurationWifiInfoWifiManager
(1)ScanResult

主要是通過wifi硬體的掃描來獲取一些周邊的wifi熱點的資訊。在我們進行wifi 搜尋的時候,一般會搜到這些資訊,首先是接入點名字、接入點資訊的強弱、還有接入點使用的安全模式,是WPA、WPE。開啟這個類,我們可以看到以下幾個資訊:

BSSID

接入點的地址,這裡主要是指小範圍幾個無線裝置相連線所獲取的地址,比如說兩臺筆記本通過無線網絡卡進行連線,雙方的無線網絡卡分配的地址。
SSID
網路的名字,當我們搜尋一個網路時,就是靠這個來區分每個不同的網路接入點。
Capabilities
網路接入的效能,這裡主要是來判斷網路的加密方式等。
Frequency
頻率,每一個頻道互動的MHz 數。
Level
等級,主要來判斷網路連線的優先數。這裡只提供了一個方法,就是將獲得資訊程式設計字串toString()
(2)wifiConfiguration

在我們連通一個wifi接入點的時候,需要獲取到的一些資訊。大家可以跟我們有線的裝置進行對比一下。

這裡的資料相對來說比較複雜一下。六個子類
WifiConfiguration.AuthAlgorthm
用來判斷加密方法。
WifiConfiguration.GroupCipher
獲取使用GroupCipher 的方法來進行加密。
WifiConfiguration.KeyMgmt
獲取使用KeyMgmt 進行。
WifiConfiguration.PairwiseCipher
獲取使用WPA 方式的加密。
WifiConfiguration.Protocol
獲取使用哪一種協議進行加密。
wifiConfiguration.Status
獲取當前網路的狀態。對於上述加密感興趣的朋友,可以在網上搜索相關的內容。
(3)WifiInfo

在我們的wifi已經連通了以後,可以通過這個類獲得一些已經連通的wifi連線的資訊獲取當前連結的資訊,這裡資訊就比較簡單了,這裡簡單介紹一下這裡的方法:
getBSSID()
獲取BSSID
getDetailedStateOf()
獲取客戶端的連通性
getHiddenSSID()
獲得SSID 是否被隱藏
getIpAddress()
獲取IP 地址
getLinkSpeed()
獲得連線的速度
getMacAddress()
獲得Mac 地址
getRssi()
獲得802.11n 網路的訊號
getSSID()
獲得SSID
getSupplicanState()
返回具體客戶端狀態的資訊
(4)wifiManager

這個不用說,就是用來管理我們的wifi連線,這裡已經定義好了一些類,可以供我們使用。這裡來說相對複雜,裡面的內容比較多,但是通過字面意思,我們還是可以獲得很多相關的資訊。這個類裡面預先定義了許多常量,我們可以直接使用,不用再次建立。這裡還是簡單介紹一下這裡的方法:
addNetwork(WifiConfigurationconfig)
通過獲取到的網路的連結狀態資訊,來新增網路
calculateSignalLevel(intrssi , int numLevels)
計算訊號的等級
compareSignalLevel(intrssiA, int rssiB)
對比連線A 和連線B
createWifiLock(intlockType, String tag)
建立一個wifi 鎖,鎖定當前的wifi 連線
disableNetwork(intnetId)
讓一個網路連線失效
disconnect()
斷開連線
enableNetwork(intnetId, Boolean disableOthers)
連線一個連線
getConfiguredNetworks()
獲取網路連線的狀態
getConnectionInfo()
獲取當前連線的資訊
getDhcpInfo()
獲取DHCP 的資訊
getScanResulats()
獲取掃描測試的結果
getWifiState()
獲取一個wifi 接入點是否有效
isWifiEnabled()
判斷一個wifi 連線是否有效
pingSupplicant()ping
一個連線,判斷是否能連通
ressociate()
即便連線沒有準備好,也要連通
reconnect()
如果連線準備好了,連通
removeNetwork()
移除某一個網路
saveConfiguration()
保留一個配置資訊
setWifiEnabled()
讓一個連線有效
startScan()
開始掃描
updateNetwork(WifiConfigurationconfig)
更新一個網路連線的資訊此外wifiManaer 還提供了一個內部的子類,也就是wifiManagerLock,WifiManagerLock 的作用是這樣的,在普通的狀態下,如果我們的wifi 的狀態處於閒置,那麼網路的連通,將會暫時中斷。但是如果我們把當前的網路狀態鎖上,那麼wifi 連通將會保持在一定狀態,當然接觸鎖定之後,就會恢復常態。

實現目標:搜尋WIFI,手動輸入密碼並儲存,連線WIFI。第二次連線該WIFI訊號不需要輸入密碼

首先在AndroidManifest.XML中開啟響應的許可權

<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"></uses-permission><!-- 允許程式改變網路連結狀態 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission><!--允許程式訪問訪問WIFI網路狀態資訊  -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission><!-- 允許程式改變WIFI連結狀態 -->
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
1、開啟WIFI
//開啟WIFI
public void WifiOpen(){
	if(!localWifiManager.isWifiEnabled()){
		localWifiManager.setWifiEnabled(true);
	}
}
2、掃描WIFI訊號
//掃描wifi
public void WifiStartScan(){
	localWifiManager.startScan();
}
3、得到掃描WIFI結果
//得到Scan結果
public List<ScanResult> getScanResults(){
	return localWifiManager.getScanResults();//得到掃描結果
}
4、得到配置好的WIFI資訊
//得到Wifi配置好的資訊
public void getConfiguration(){
	wifiConfigList = localWifiManager.getConfiguredNetworks();//得到配置好的網路資訊
	for(int i =0;i<wifiConfigList.size();i++){
		Log.i("getConfiguration",wifiConfigList.get(i).SSID);
		Log.i("getConfiguration",String.valueOf(wifiConfigList.get(i).networkId));
	}
}

5、根據WIFI的名稱SSID判定指定WIFI是否已經配置好,配置好則返回其networkId,用於連線。之前嘗試了BSSID地址沒成功,所以只能使用SSID

//判定指定WIFI是否已經配置好,依據WIFI的地址BSSID,返回NetId
public int IsConfiguration(String SSID){
	Log.i("IsConfiguration",String.valueOf(wifiConfigList.size()));
	for(int i = 0; i < wifiConfigList.size(); i++){
		Log.i(wifiConfigList.get(i).SSID,String.valueOf( wifiConfigList.get(i).networkId));
		if(wifiConfigList.get(i).SSID.equals(SSID)){//地址相同
    		return wifiConfigList.get(i).networkId;
		}
	}
	return -1;
}

6、如果需要連線的WIFI沒有配置好,即沒有儲存密碼。則為指定名稱ssidWIFI新增密碼資訊psw,新增成功後返回給其分配的networId,同於連線

//新增指定WIFI的配置資訊,原列表不存在此SSID
public int AddWifiConfig(List<ScanResult> wifiList,String ssid,String pwd){
	int wifiId = -1;
	for(int i = 0;i < wifiList.size(); i++){
		ScanResult wifi = wifiList.get(i);
		if(wifi.SSID.equals(ssid)){
			Log.i("AddWifiConfig","equals");
			WifiConfiguration wifiCong = new WifiConfiguration();
			wifiCong.SSID = "\""+wifi.SSID+"\"";//\"轉義字元,代表"
			wifiCong.preSharedKey = "\""+pwd+"\"";//WPA-PSK密碼
			wifiCong.hiddenSSID = false;
			wifiCong.status = WifiConfiguration.Status.ENABLED;
			wifiId = localWifiManager.addNetwork(wifiCong);//將配置好的特定WIFI密碼資訊新增,新增完成後預設是不啟用狀態,成功返回ID,否則為-1
			if(wifiId != -1){
				return wifiId;
			}
		}
	}
	return wifiId;
}
7、根據步驟6配置好需要連線的WIFI密碼資訊後,下面通過networkId連線指定WIFI。在連線經過步驟6剛新增配置資訊的WIFI訊號之前需要重新執行下步驟4,得到新的配置好資訊的列表
//連線指定Id的WIFI
public boolean ConnectWifi(int wifiId){
         for(int i = 0; i < wifiConfigList.size(); i++){
                 WifiConfiguration wifi = wifiConfigList.get(i);
                 if(wifi.networkId == wifiId){
                          while(!(localWifiManager.enableNetwork(wifiId, true))){//啟用該Id,建立連線
                              //status:0--已經連線,1--不可連線,2--可以連線
                                   Log.i("ConnectWifi",String.valueOf(wifiConfigList.get(wifiId).status));
                          }
                          return true;
                 }
         }
         return false;
}

文章來源: 感謝分享