Android平臺(tái)下的WIFI模塊功能
1.開(kāi)關(guān)WIFI
除了在WIFI設(shè)置界面可以開(kāi)關(guān)WIFI,還有其他的方法可以設(shè)置,要查看這些開(kāi)關(guān)狀態(tài)是否一致。還有就是飛行模式對(duì)WIFI開(kāi)關(guān)的影響,由于WIFI開(kāi)和關(guān)都有一個(gè)時(shí)間過(guò)程,而飛行模式的開(kāi)關(guān)瞬間完成,所以有時(shí)會(huì)出現(xiàn)沖突。
2.開(kāi)關(guān)新可用網(wǎng)絡(luò)提醒
新可用網(wǎng)絡(luò)的定義是自WIFI模塊開(kāi)啟后,從未發(fā)現(xiàn)過(guò)的,為加密的網(wǎng)絡(luò)。只有滿足了新可用網(wǎng)絡(luò)的定義,才會(huì)有提醒。
3.連接斷開(kāi)網(wǎng)絡(luò)
連接斷開(kāi)各種不同加密類型的網(wǎng)絡(luò)(具體類型下文有詳解)
4.手動(dòng)添加網(wǎng)絡(luò)
需要路由器關(guān)閉SIID廣播??墒謩?dòng)輸入SIID,網(wǎng)絡(luò)加密類型,密碼。對(duì)于OPAL手機(jī)來(lái)說(shuō),路由器隱藏了SSID,手動(dòng)添加的網(wǎng)絡(luò)是無(wú)法連接的。
5.搜索網(wǎng)絡(luò)
手動(dòng)點(diǎn)擊搜索按鈕可以搜索網(wǎng)絡(luò),也可以等待WIFI模塊自動(dòng)搜索網(wǎng)絡(luò)。
6.休眠設(shè)置
由于WIFI模塊是用電大戶,所有為了省電,Android的WIFI加了一個(gè)休眠策略,可以設(shè)置永遠(yuǎn)不斷開(kāi),充電時(shí)不斷開(kāi)和鎖屏?xí)r斷開(kāi)。要測(cè)試休眠設(shè)置是否有效,可以在路由器上PING手機(jī)的IP,PING通就是連接狀態(tài)。OPAL手機(jī)的休眠策略屬于完全失效,現(xiàn)在的情況是無(wú)論選哪個(gè)都會(huì)一直保持連接,鎖屏后15分鐘再休眠。
7.設(shè)置靜態(tài)IP
Android系統(tǒng)里對(duì)IP設(shè)置的輸入限制很有問(wèn)題,我一直認(rèn)為這是弱智的限制。正常IP的范圍在0-255之間,android對(duì)IP輸入的限制是整數(shù)0到整數(shù)255之間,也就是說(shuō)0000.000200.001.001這樣一個(gè)IP都能合法輸入。
熱點(diǎn)加密類型
目前,常見(jiàn)及需要處理的熱點(diǎn),包括以下3大類:
open——開(kāi)放型網(wǎng)絡(luò),即無(wú)加密,可直接連接
wep——采用wep加密類型的熱點(diǎn),已過(guò)時(shí),不安全,容易被破解,目前使用率已不足10%
wpa/wpa2——目前使用最廣泛,相對(duì)最安全,破解難度最大的加密類型
wps(wifiprotectedsetup):是為了進(jìn)一步增強(qiáng)wpa熱點(diǎn)及簡(jiǎn)化連接過(guò)程的技術(shù),不屬于加密類型。
android的wifi模塊功能開(kāi)發(fā)教程
1、獲取WifiManager入口類實(shí)例
wifiManager = (WifiManager) context
.getSystemService(Context.WIFI_SERVICE);12
2、打開(kāi)及關(guān)閉wifi
wifiManager.setWifiEnabled(true)1
true表示打開(kāi)wifi開(kāi)關(guān),false表示關(guān)閉,該方法的返回值僅代表操作是否成功,不代表wifi狀態(tài)的變化;
通過(guò)監(jiān)聽(tīng)廣播WifiManager.WIFI_STATE_CHANGED_ACTION ,來(lái)判斷真正的wifi開(kāi)關(guān)變化,該廣播帶有一個(gè)int型的值來(lái)表示wifi狀態(tài):
int wifistate = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
WifiManager.WIFI_STATE_DISABLED);
switch (wifistate) {
case WifiManager.WIFI_STATE_DISABLED:
//wifi已關(guān)閉
break;
case WifiManager.WIFI_STATE_ENABLED:
//wifi已打開(kāi)
break;
case WifiManager.WIFI_STATE_ENABLING:
//wifi正在打開(kāi)
break;
default:
break;
}123456789101112131415
可以看到,該操作其實(shí)是一個(gè)異步操作,一般耗時(shí)在1~3秒之間。
3、周圍熱點(diǎn)掃描
wifiManager.startScan()1
以上方法為開(kāi)始掃描的接口,其返回值代表操作是否成功,掃描結(jié)果通過(guò)另外一個(gè)接口獲?。?/p>
List《ScanResult》 results = wifiManager.getScanResults();1
一般在主動(dòng)調(diào)用startScan之后,大概2秒左右,會(huì)收到WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)廣播通知,該廣播包括一個(gè)boolean型的額外參數(shù):
boolean isScanned = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, true);1
上面的值表示,掃描結(jié)果是否已可用,若可用,則可以使用getScanResults獲取結(jié)果,在結(jié)果沒(méi)有就緒之前,會(huì)返回null。
一般系統(tǒng)本身會(huì)調(diào)用startScan接口,而該操作相對(duì)比較耗電,因此在應(yīng)用中要酌情使用,并不需要頻繁調(diào)用。
4、獲取已連接過(guò)的熱點(diǎn)
所有已經(jīng)連接過(guò)的熱點(diǎn),都會(huì)存在本地一個(gè)文件中,一般路徑為/data/misc/wifi/wpa_supplicant.conf(查看需root),而在程序中獲取則通過(guò)以下接口:
List《WifiConfiguration》 configurations = wifiManager.getConfiguredNetworks();1
獲取到的WiFiConfiguration對(duì)象中,只有ssid和networkId是一定有的,可以用于直接連接該熱點(diǎn),其他信息如bssid,密鑰等信息基本都是空的。(如何直接連接熱點(diǎn),下文敘述)
5、獲取當(dāng)前wifi連接信息
WifiInfo info = wifiManager.getConnectionInfo();1
該對(duì)象代表當(dāng)前已連接的熱點(diǎn),信息,無(wú)連接時(shí)返回null;
該對(duì)象可獲取包括ssid,bssid,networkId等信息,而ssid是包括了雙引號(hào)的,如“CCMC”,在之前的掃描結(jié)果ScanResult中,ssid并不帶雙引號(hào)。
6、連接指定熱點(diǎn)
連接一個(gè)未連接過(guò)的熱點(diǎn)時(shí),需3步:
1)創(chuàng)建一個(gè)配置:WifiConfiguration
public WifiConfiguration createConfiguration(AccessPoint ap) {
String SSID = ap.getSsid();
WifiConfiguration config = new WifiConfiguration();
config.SSID = “”“ + SSID + ”“”;
String encryptionType = ap.getEncryptionType();
String password = ap.getPassword();
if (encryptionType.contains(“wep”)) {
/**
* special handling according to password length is a must for wep
*/
int i = password.length();
if (((i == 10 || (i == 26) || (i == 58))) && (password.matches(“[0-9A-Fa-f]*”))) {
config.wepKeys[0] = password;
} else {
config.wepKeys[0] = “”“ + password + ”“”;
}
config.allowedAuthAlgorithms
.set(WifiConfiguration.AuthAlgorithm.SHARED);
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
config.wepTxKeyIndex = 0;
} else if (encryptionType.contains(“wpa”)) {
config.preSharedKey = “”“ + password + ”“”;
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
} else {
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
}
return config;
}123456789101112131415161718192021222324252627282930
*網(wǎng)上流傳多處創(chuàng)建configuration的代碼,但大都未經(jīng)過(guò)驗(yàn)證,以上代碼已經(jīng)經(jīng)過(guò)了線上版本測(cè)試,準(zhǔn)確可用。
判斷加密類型的方式,可以優(yōu)化,本處僅示例。*
2)生成一個(gè)networkId
WifiConfiguration config = createConfiguration(ap);
/**
* networkId is bigger than 0 in most time, 0 in few time and smaller than 0 in no time
*/
int networkId = networkId = wifiManager.addNetwork(config);123456
一般情況下,對(duì)一個(gè)已經(jīng)連接過(guò)的熱點(diǎn)(本地有連接記錄),進(jìn)行以上操作時(shí),在api21及以上會(huì)返回一個(gè)小于0的networkId,此時(shí),進(jìn)行下一步連接是沒(méi)有意義的,獲得一個(gè)小于0的networkId已經(jīng)表示連接失敗。
3)開(kāi)始連接
wifiManager.enableNetwork(networkId, true)1
對(duì)于已經(jīng)連接過(guò)的熱點(diǎn),通過(guò)小項(xiàng)4 中的方式,獲取到該熱點(diǎn)的networkId之后,可直接進(jìn)行第三步的連接,無(wú)需1)2);
若有必要進(jìn)行12步(如嘗試一個(gè)新密碼,因?yàn)榧词故褂昧隋e(cuò)誤的密碼連接,系統(tǒng)還是會(huì)為本次連接生成一個(gè)本地記錄),則必須在一開(kāi)始,將本地記錄remove掉,remove操作將在下文介紹。
連接結(jié)果通過(guò)兩個(gè)廣播反饋:WifiManager.NETWORK_STATE_CHANGED_ACTION和WifiManager.SUPPLICANT_STATE_CHANGED_ACTION
其中,密碼錯(cuò)誤的結(jié)果通知需通過(guò)第二個(gè)廣播判斷:
int error = intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, 0);
if (WifiManager.ERROR_AUTHENTICATING == error) {
//密碼錯(cuò)誤,認(rèn)證失敗
}1234
其他結(jié)果均通過(guò)第一個(gè)廣播接收:
if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
if (null != info) {
NetworkInfo.DetailedState state = info.getDetailedState();
}
}123456
public enum DetailedState {
/** Ready to start data connection setup. */
IDLE,
/** Searching for an available access point. */
SCANNING,
/** Currently setting up data connection. */
CONNECTING,
/** Network link established, performing authentication. */
AUTHENTICATING,
/** Awaiting response from DHCP server in order to assign IP address information. */
OBTAINING_IPADDR,
/** IP traffic should be available. */
CONNECTED,
/** IP traffic is suspended */
SUSPENDED,
/** Currently tearing down data connection. */
DISCONNECTING,
/** IP traffic not available. */
DISCONNECTED,
/** Attempt to connect failed. */
FAILED,
/** Access to this network is blocked. */
BLOCKED,
/** Link has poor connectivity. */
VERIFYING_POOR_LINK,
/** Checking if network is a captive portal */
CAPTIVE_PORTAL_CHECK
}12345678910111213141516171819202122232425262728
7、斷開(kāi)當(dāng)前wifi連接
wifiManager.disconnect()1
以上接口返回值代表當(dāng)前操作是否成功,操作的最終結(jié)果,會(huì)在兩個(gè)廣播中有所反饋:
WifiManager.SUPPLICANT_STATE_CHANGED_ACTION
WifiManager.NETWORK_STATE_CHANGED_ACTION
并且斷開(kāi)成功的廣播會(huì)發(fā)送若干次。
8、遺忘一個(gè)已連接過(guò)的熱點(diǎn)
boolean isRemoved = wifiManager.removeNetwork(networkId)1
返回值代表操作是否成功,該操作在api21以上的系統(tǒng)中,成功率在10%以下,在api21以下,基本都可以成功;
可以通過(guò)反復(fù)進(jìn)行此操作來(lái)提高成功率,但效果不大。
評(píng)論