這里列了很多,但是大致可以分為四個主要的類ScanResult wifiConfiguration WifiInfo WifiManager
(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 獲取當前網絡的狀態。
對於上述加密感興趣的朋友,可以在網上搜索相關的內容。
設置WifiConfiguration的屬性:
WifiConfiguration.AuthAlgorthm 設置加密方法。
可選參數:LEAP只用於leap,
OPEN 被wpa/wpa2需要,
SHARED需要一個靜態的wep key
WifiConfiguration.GroupCipher 使用GroupCipher 的方法來進行加密。
可選參數:CCMP,TKIP,WEP104,WEP40
WifiConfiguration.KeyMgmt 鍵管理機制(keymanagerment),使用KeyMgmt 進行。
可選參數IEEE8021X,NONE,WPA_EAP,WPA_PSK
WifiConfiguration.PairwiseCipher 設置加密方式。
可選參數 CCMP,NONE,TKIP
WifiConfiguration.Protocol 設置一種協議進行加密。
可選參數 RSN,WPA,
wifiConfiguration.Status 設置當前網絡的狀態。
可選參數CURRENT,DISABLED,ENABLED,
(3)WifiInfo 在我們的wifi 已經連通了以后,可以通過這個類獲得一些已經連通的wifi 連接的信息獲取當前鏈接的信息,
這里信息就比較簡單了,這里簡單介紹一下這里的方法:
getBSSID() 獲取BSSID
getDetailedStateOf() 獲取客戶端的連通性
getHiddenSSID() 獲得SSID 是否被隱藏
getIpAddress() 獲取IP 地址
getLinkSpeed() 獲得連接的速度
getMacAddress() 獲得Mac 地址
getRssi() 獲得802.11n 網絡的信號
getSSID() 獲得SSID
getSupplicanState() 返回具體客戶端狀態的信息
(4)wifiManager 這個不用說,就是用來管理我們的wifi 連接,這里已經定義好了一些類,可以供我們使用。
這里來說相對復雜,里面的內容比較多,但是通過字面意思,我們還是可以獲得很多相關的信息。這個類里面預先定義了許多常量,我們可以直接使用,不用再次創建。
這里還是簡單介紹一下這里的方法:
addNetwork(WifiConfiguration config) 通過獲取到的網絡的鏈接狀態信息,來添加網絡
calculateSignalLevel(int rssi , int numLevels) 計算信號的等級
compareSignalLevel(int rssiA, int rssiB) 對比連接A 和連接B
createWifiLock(int lockType, String tag) 創建一個wifi 鎖,鎖定當前的wifi 連接
disableNetwork(int netId) 讓一個網絡連接失效
disconnect() 斷開連接
enableNetwork(int netId, Boolean disableOthers) 連接一個連接
getConfiguredNetworks() 獲取網絡連接的狀態
getConnectionInfo() 獲取當前連接的信息
getDhcpInfo() 獲取DHCP 的信息
getScanResulats() 獲取掃描測試的結果
getWifiState() 獲取一個wifi 接入點是否有效
isWifiEnabled() 判斷一個wifi 連接是否有效
pingSupplicant() ping 一個連接,判斷是否能連通
ressociate() 即便連接沒有准備好,也要連通
reconnect() 如果連接准備好了,連通
removeNetwork() 移除某一個網絡
saveConfiguration() 保留一個配置信息
setWifiEnabled() 讓一個連接有效
startScan() 開始掃描
updateNetwork(WifiConfiguration config) 更新一個網絡連接的信息
此外wifiManaer 還提供了一個內部的子類,也就是wifiManagerLock,WifiManagerLock 的作用是這樣的,
在普通的狀態下,如果我們的wifi 的狀態處於閑置,那么網絡的連通,將會暫時中斷。
但是如果我們把當前的網絡狀態鎖上,那么wifi 連通將會保持在一定狀態,當然接觸鎖定之后,就會恢復常態
但是關於鏈接加密的wifi現在還沒有成功……
附一個WifiAdmin 管理類:
package youcan.text;
import java.util.List;
import android.content.Context;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock;
public class WifiAdmin {
// 定義WifiManager對象
private WifiManager mWifiManager;
// 定義WifiInfo對象
private WifiInfo mWifiInfo;
// 掃描出的網絡連接列表
private List<ScanResult> mWifiList;
// 網絡連接列表
private List<WifiConfiguration> mWifiConfiguration;
// 定義一個WifiLock
WifiLock mWifiLock;
// 構造器
public WifiAdmin(Context context) {
// 取得WifiManager對象
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
// 取得WifiInfo對象
mWifiInfo = mWifiManager.getConnectionInfo();
}
// 得到WifiManager對象
public WifiManager GetWifiManager() {
return mWifiManager;
}
// 打開WIFI
public void OpenWifi() {
if (!mWifiManager.isWifiEnabled()) {
mWifiManager.setWifiEnabled(true);
}
}
// 關閉WIFI
public void CloseWifi() {
if (!mWifiManager.isWifiEnabled()) {
mWifiManager.setWifiEnabled(false);
}
}
// 鎖定WifiLock
public void AcquireWifiLock() {
mWifiLock.acquire();
}
// 解鎖WifiLock
public void ReleaseWifiLock() {
// 判斷時候鎖定
if (mWifiLock.isHeld()) {
mWifiLock.acquire();
}
}
// 創建一個WifiLock
public void CreatWifiLock() {
mWifiLock = mWifiManager.createWifiLock("Test");
}
// 得到配置好的網絡
public List<WifiConfiguration> GetConfiguration() {
return mWifiConfiguration;
}
// 指定配置好的網絡進行連接
public void ConnectConfiguration(int index) {
// 索引大於配置好的網絡索引返回
if (index > mWifiConfiguration.size()) {
return;
}
// 連接配置好的指定ID的網絡
mWifiManager.enableNetwork(mWifiConfiguration.get(index).networkId,
true);
}
public void StartScan() {
mWifiManager.startScan();
// 得到掃描結果
mWifiList = mWifiManager.getScanResults();
// 得到配置好的網絡連接
mWifiConfiguration = mWifiManager.getConfiguredNetworks();
}
// 得到網絡列表
public List<ScanResult> GetWifiList() {
return mWifiList;
}
// 查看掃描結果
public StringBuilder LookUpScan() {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < mWifiList.size(); i++) {
stringBuilder
.append("Index_" + new Integer(i + 1).toString() + ":");
// 將ScanResult信息轉換成一個字符串包
// 其中把包括:BSSID、SSID、capabilities、frequency、level
stringBuilder.append((mWifiList.get(i)).toString());
stringBuilder.append("n");
}
return stringBuilder;
}
// 得到MAC地址
public String GetMacAddress() {
return (mWifiInfo == null) ? "NULL" : mWifiInfo.getMacAddress();
}
// 得到接入點的BSSID
public String GetBSSID() {
return (mWifiInfo == null) ? "NULL" : mWifiInfo.getBSSID();
}
// 得到IP地址
public int GetIPAddress() {
return (mWifiInfo == null) ? 0 : mWifiInfo.getIpAddress();
}
// 得到連接的ID
public int GetNetworkId() {
return (mWifiInfo == null) ? 0 : mWifiInfo.getNetworkId();
}
// 得到WifiInfo的所有信息包
public String GetWifiInfo() {
return (mWifiInfo == null) ? "NULL" : mWifiInfo.toString();
}
// 添加一個網絡並連接
public void AddNetwork(WifiConfiguration wcg) {
int wcgID = mWifiManager.addNetwork(wcg);
mWifiManager.enableNetwork(wcgID, true);
}
// 斷開指定ID的網絡
public void DisconnectWifi(int netId) {
mWifiManager.disableNetwork(netId);
mWifiManager.disconnect();
}
}
======================================android wifi啟動過程======================================
初始化
在 SystemServer 啟動的時候,會生成一個 ConnectivityService 的實例,
try {
Log.i(TAG, "Starting Connectivity Service.");
ServiceManager.addService(Context.CONNECTIVITY_SERVICE, new ConnectivityService(context));
} catch (Throwable e) {
Log.e(TAG, "Failure starting Connectivity Service", e);
}
ConnectivityService 的構造函數會創建 WifiService,
if (DBG) Log.v(TAG, "Starting Wifi Service.");
mWifiStateTracker = new WifiStateTracker(context, handler);
WifiService wifiService = new WifiService(context, mWifiStateTracker);
ServiceManager.addService(Context.WIFI_SERVICE, wifiService);
WifiStateTracker 會創建 WifiMonitor 接收來自底層的事件,
WifiService 和 WifiMonitor 是整個模塊的核心。
WifiService 負責啟動關閉 wpa_supplicant、啟動關閉 WifiMonitor 監視線程和把命令下發給 wpa_supplicant,
而 WifiMonitor 則負責從 wpa_supplicant 接收事件通知。
連接 AP
1. 使能 WIFI
WirelessSettings 在初始化的時候配置了由 WifiEnabler 來處理 Wifi 按鈕,
private void initToggles() {
mWifiEnabler = new WifiEnabler(
this,
(WifiManager) getSystemService(WIFI_SERVICE),
(CheckBoxPreference) findPreference(KEY_TOGGLE_WIFI)
);
}
當用戶按下 Wifi 按鈕后,Android 會調用 WifiEnabler 的 onPreferenceChange,
再由 WifiEnabler調用 WifiManager 的 setWifiEnabled 接口函數,
通過 AIDL,實際調用的是 WifiService 的setWifiEnabled 函數,
WifiService 接着向自身發送一條 MESSAGE_ENABLE_WIFI 消息,
在處理該消息的代碼中做真正的使能工作:
首先裝載 WIFI 內核模塊(該模塊的位置硬編碼為"/system/lib/modules/wlan.ko" ),
然 后 啟 動 wpa_supplicant ( 配 置 文 件 硬 編 碼為"/data/misc/wifi/wpa_supplicant.conf")
再通過 WifiStateTracker 來啟動 WifiMonitor 中的監視線程。
private boolean setWifiEnabledBlocking(boolean enable) {
final int eventualWifiState = enable ? WIFI_STATE_ENABLED : WIFI_STATE_DISABLED;
updateWifiState(enable ? WIFI_STATE_ENABLING : WIFI_STATE_DISABLING);
if (enable) {
if (!WifiNative.loadDriver()) {
Log.e(TAG, "Failed to load Wi-Fi driver.");
updateWifiState(WIFI_STATE_UNKNOWN);
return false;
}
if (!WifiNative.startSupplicant()) {
WifiNative.unloadDriver();
Log.e(TAG, "Failed to start supplicant daemon.");
updateWifiState(WIFI_STATE_UNKNOWN);
return false;
}
mWifiStateTracker.startEventLoop();
}
// Success!
persistWifiEnabled(enable);
updateWifiState(eventualWifiState);
return true;
}
當使能成功后,會廣播發送 WIFI_STATE_CHANGED_ACTION 這個 Intent 通知外界 WIFI 已經成功使能了。
WifiEnabler 創建的時候就會向 Android 注冊接收WIFI_STATE_CHANGED_ACTION,
因此它會收到該 Intent,從而開始掃描。
private void handleWifiStateChanged(int wifiState) {
if (wifiState == WIFI_STATE_ENABLED) {
loadConfiguredAccessPoints();
attemptScan();
}
2. 查找 AP
掃描的入口函數是 WifiService 的 startScan,它其實也就是往 wpa_supplicant 發送 SCAN 命令。
static jboolean android_net_wifi_scanCommand(JNIEnv* env, jobject clazz)
{
jboolean result;
// Ignore any error from setting the scan mode.
// The scan will still work.
(void)doBooleanCommand("DRIVER SCAN-ACTIVE", "OK");
result = doBooleanCommand("SCAN", "OK");
(void)doBooleanCommand("DRIVER SCAN-PASSIVE", "OK");
return result;
}
當 wpa_supplicant 處理完 SCAN 命令后,它會向控制通道發送事件通知掃描完成,
從而wifi_wait_for_event 函數會接收到該事件,
由此 WifiMonitor 中的 MonitorThread 會被執行來出來這個事件,
void handleEvent(int event, String remainder) {
case SCAN_RESULTS:
mWifiStateTracker.notifyScanResultsAvailable();
break;
WifiStateTracker 則接着廣播發送 SCAN_RESULTS_AVAILABLE_ACTION 這個 Intent
case EVENT_SCAN_RESULTS_AVAILABLE:
mContext.sendBroadcast(new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
WifiLayer 注冊了接收 SCAN_RESULTS_AVAILABLE_ACTION 這個 Intent,所以它的相關
處理函數 handleScanResultsAvailable 會被調用,在該函數中,先會去拿到 SCAN 的結果(最
終是往 wpa_supplicant 發送 SCAN_RESULT 命令並讀取返回值來實現的) ,
List<ScanResult> list = mWifiManager.getScanResults();
對每一個掃描返回的 AP,WifiLayer 會調用 WifiSettings 的 onAccessPointSetChanged 函數,
從而最終把該 AP 加到 GUI 顯示列表中。
public void onAccessPointSetChanged(AccessPointState ap, boolean added) {
AccessPointPreference pref = mAps.get(ap);
if (added) {
if (pref == null) {
pref = new AccessPointPreference(this, ap);
mAps.put(ap, pref);
} else {
pref.setEnabled(true);
}
mApCategory.addPreference(pref);
}
}
3. 配置 AP 參數
當用戶在 WifiSettings 界面上選擇了一個 AP 后,會顯示配置 AP 參數的一個對話框,
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
if (preference instanceof AccessPointPreference) {
AccessPointState state = ((AccessPointPreference) preference).getAccessPointState();
showAccessPointDialog(state, AccessPointDialog.MODE_INFO);
}
}
4. 連接
當用戶在 AcessPointDialog 中選擇好加密方式和輸入密鑰之后,再點擊連接按鈕,Android
就會去連接這個 AP。
private void handleConnect() {
String password = getEnteredPassword();
if (!TextUtils.isEmpty(password)) {
mState.setPassword(password);
}
mWifiLayer.connectToNetwork(mState);
}
WifiLayer 會先檢測這個 AP 是不是之前被配置過,這個是通過向 wpa_supplicant 發送
LIST_NETWORK 命令並且比較返回值來實現的,
// Need WifiConfiguration for the AP
WifiConfiguration config = findConfiguredNetwork(state);
如果 wpa_supplicant 沒有這個 AP 的配置信息,則會向 wpa_supplicant 發送 ADD_NETWORK 命令來添加該 AP,
if (config == null) {
// Connecting for the first time, need to create it
config = addConfiguration(state, ADD_CONFIGURATION_ENABLE|ADD_CONFIGURATION_SAVE);
}
ADD_NETWORK 命 令 會 返 回 一 個 ID , WifiLayer 再用這個返回的ID作為參數向
wpa_supplicant 發送 ENABLE_NETWORK 命令,從而讓 wpa_supplicant 去連接該 AP。
// Make sure that network is enabled, and disable others
mReenableApsOnNetworkStateChange = true;
if (!mWifiManager.enableNetwork(state.networkId, true)) {
Log.e(TAG, "Could not enable network ID " + state.networkId);
error(R.string.error_connecting);
return false;
}
5. 配置 IP 地址
當 wpa_supplicant 成功連接上 AP 之后,它會向控制通道發送事件通知連接上 AP 了,從而
wifi_wait_for_event 函數會接收到該事件,由此 WifiMonitor 中的 MonitorThread 會被執行來
出來這個事件,
void handleEvent(int event, String remainder) {
case CONNECTED:
handleNetworkStateChange(NetworkInfo.DetailedState.CONNECTED,remainder);
break;
WifiMonitor 再調用 WifiStateTracker 的 notifyStateChange,WifiStateTracker 則接着會往自身
發送 EVENT_DHCP_START 消息來啟動 DHCP 去獲取 IP 地址,
private void handleConnectedState() {
setPollTimer();
mLastSignalLevel = -1;
if (!mHaveIPAddress && !mObtainingIPAddress) {
mObtainingIPAddress = true;
mDhcpTarget.obtainMessage(EVENT_DHCP_START).sendToTarget();
}
}
然后再廣播發送 NETWORK_STATE_CHANGED_ACTION 這個 Intent
case EVENT_NETWORK_STATE_CHANGED:
if (result.state != DetailedState.DISCONNECTED || !mDisconnectPending) {
intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, mNetworkInfo);
if (result.BSSID != null)
intent.putExtra(WifiManager.EXTRA_BSSID, result.BSSID);
mContext.sendStickyBroadcast(intent);
}
break;
WifiLayer 注冊了接收 NETWORK_STATE_CHANGED_ACTION 這個 Intent,所以它的相關
處理函數 handleNetworkStateChanged 會被調用,
當 DHCP 拿到 IP 地址之后,會再發送 EVENT_DHCP_SUCCEEDED 消息,
private class DhcpHandler extends Handler {
public void handleMessage(Message msg) {
switch (msg.what) {
case EVENT_DHCP_START:
if (NetworkUtils.runDhcp(mInterfaceName, mDhcpInfo)) {
event = EVENT_DHCP_SUCCEEDED;
}
WifiLayer 處理 EVENT_DHCP_SUCCEEDED 消息 , 會再次廣播發送
NETWORK_STATE_CHANGED_ACTION 這個 Intent,這次帶上完整的 IP 地址信息。
case EVENT_DHCP_SUCCEEDED:
mWifiInfo.setIpAddress(mDhcpInfo.ipAddress);
setDetailedState(DetailedState.CONNECTED);
intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, mNetworkInfo);
mContext.sendStickyBroadcast(intent);
break;
至此為止,整個連接過程完成
WifiManager wifi = (WifiManager)getSystemService(Context.WIFI_SERVICE);
WifiConfiguration wc = new WifiConfiguration();
wc.SSID = ""test"";//ssid
wc.preSharedKey = ""12345678"";//ssid密碼
wc.hiddenSSID = true;
wc.status = WifiConfiguration.Status.ENABLED;
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
int res = wifi.addNetwork(wc);
Log.e("WifiPreference", "add Network returned " + res );
boolean b = wifi.enableNetwork(res, true);
Log.e("WifiPreference", "enableNetwork returned " + b );
=====================================================================
package src.hero.com;
import java.util.ArrayList;
import java.util.List;
import android.app.ListActivity;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;
public class ListOk extends ListActivity implements OnItemClickListener
{
private ListView lv;
private WifiTester wifiTester;
// -----------------------連接WIFI
private ScanResult scanRet;
private WifiConfiguration wc;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.setTitle("當前可用的WIFI列表");
WifiTesterApp _TestActivityApp = (WifiTesterApp) this.getApplication();
wifiTester = (_TestActivityApp).getWifiTester();
wc = new WifiConfiguration();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
getString(wifiTester.getWifiList()));
setListAdapter(adapter);
lv = getListView();
lv.setAdapter(adapter);
lv.setOnItemClickListener(this);
}
public String[] getString(List<ScanResult> wifiList)
{
ArrayList<String> listStr = new ArrayList<String>();
for (int i = 0; i < wifiList.size(); i++)
{
listStr.add(wifiList.get(i).toString());
}
return listStr.toArray(new String[0]);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id)
{
scanRet = wifiTester.getWifiList().get(position);
wc.SSID = """ + scanRet.SSID + """; // 配置wifi的SSID,即該熱點的名稱,如:TP-link_xxx
wc.preSharedKey = ""7675781777""; // 該熱點的密碼
wc.hiddenSSID = true;
wc.status = WifiConfiguration.Status.ENABLED;
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
// int res = wifiTester.getMainWifi().addNetwork(wc);
// Log.d("Wif iPreference", "1111111add Network returned " + res);
// boolean b = wifiTester.getMainWifi().enableNetwork(res, true);
// Log.d("WifiPreference", "2222222222enableNetwork returned " + b);
}
}
============================================================
package jmu84xu.all;
import java.net.Inet4Address;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;
import android.widget.CompoundButton.OnCheckedChangeListener;
public class WifiSet extends Activity implements OnCheckedChangeListener {
private WifiManager wifiManager;
private WifiInfo wifiInfo;
private CheckBox chkOpenCloseWifiBox;
private List<WifiConfiguration> wifiConfigurations;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);// 獲得WifiManager對象
wifiInfo = wifiManager.getConnectionInfo();// 獲得連接信息對象
chkOpenCloseWifiBox = (CheckBox)findViewById(R.id.chkOpenCloseWifi);
TextView tvWifiConfigurations = (TextView) findViewById(R.id.tvWifiConfigurations);
TextView tvWifiInfo = (TextView) findViewById(R.id.tvWifiInfo);
chkOpenCloseWifiBox.setOnCheckedChangeListener(this);
// 根據當前WIFI的狀態(是否被打開)設置復選框的選中狀態
if (wifiManager.isWifiEnabled()) {
chkOpenCloseWifiBox.setText("Wifi已開啟");
chkOpenCloseWifiBox.setChecked(true);
}
else {
chkOpenCloseWifiBox.setText("Wifi已關閉");
chkOpenCloseWifiBox.setChecked(false);
}
// 獲得WIFI信息
StringBuffer sb = new StringBuffer();
sb.append("Wifi信息n");
sb.append("MAC地址:" + wifiInfo.getMacAddress() + "n");
sb.append("接入點的BSSID:" + wifiInfo.getBSSID() + "n");
sb.append("IP地址(int):" + wifiInfo.getIpAddress() + "n");
sb.append("IP地址(Hex):" + Integer.toHexString(wifiInfo.getIpAddress()) + "n");
sb.append("IP地址:" + ipIntToString(wifiInfo.getIpAddress()) + "n");
sb.append("網絡ID:" + wifiInfo.getNetworkId() + "n");
tvWifiInfo.setText(sb.toString());
// 得到配置好的網絡
wifiConfigurations = wifiManager.getConfiguredNetworks();
tvWifiConfigurations.setText("已連接的無線網絡n");
for (WifiConfiguration wifiConfiguration : wifiConfigurations) {
tvWifiConfigurations.setText(tvWifiConfigurations.getText() + wifiConfiguration.SSID + "n"
);
}
}
// 將int類型的IP轉換成字符串形式的IP
private 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"";
}
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// 當選中復選框時打開WIFI
if (isChecked) {
wifiManager.setWifiEnabled(true);
chkOpenCloseWifiBox.setText("Wifi已開啟");
}
// 當取消復選框選中狀態時關閉WIFI
else {
wifiManager.setWifiEnabled(false);
chkOpenCloseWifiBox.setText("Wifi已關閉");
}
}
}
在AndroidManifest.xml文件中要使用如下的代碼打開相應的權限。
Java代碼:
XML/HTML代碼
<uses-permissionandroid:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permissionandroid:name="android.permission.WAKE_LOCK"></uses-permission>
<uses-permissionandroid:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
================================================================
package com.eoeandroid.demo.testcode;
import java.util.List;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
public class WifiTester extends Activity {
TextView mainText;
WifiManager mainWifi;
WifiReceiver receiverWifi;
List<ScanResult> wifiList;
StringBuilder sb = new StringBuilder();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.WifiTester);
setTitle("eoe教程: Wifi Test. -by:IceskYsl");
mainText = (TextView) findViewById(R.id.wifi);
mainWifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
receiverWifi = new WifiReceiver();
registerReceiver(receiverWifi, new IntentFilter(
WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
mainWifi.startScan();
mainText.setText("nStarting Scan...n");
}
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, 0, 0, "Refresh");
return super.onCreateOptionsMenu(menu);
}
public boolean onMenuItemSelected(int featureId, MenuItem item) {
mainWifi.startScan();
mainText.setText("Starting Scan");
return super.onMenuItemSelected(featureId, item);
}
protected void onPause() {
unregisterReceiver(receiverWifi);
super.onPause();
}
protected void onResume() {
registerReceiver(receiverWifi, new IntentFilter(
WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
super.onResume();
}
class WifiReceiver extends BroadcastReceiver {
public void onReceive(Context c, Intent intent) {
sb = new StringBuilder();
wifiList = mainWifi.getScanResults();
for (int i = 0; i < wifiList.size(); i++) {
sb.append(new Integer(i + 1).toString() + ".");
sb.append((wifiList.get(i)).toString());
sb.append("nn");
}
mainText.setText(sb);
}
}
}
================================================================
1.wifi的五種狀態:
WIFI_STATE_DISABLED WIFI網卡不可用
WIFI_STATE_DISABLING WIFI網卡正在關閉
WIFI_STATE_ENABLED WIFI網卡可用
WIFI_STATE_ENABLING WIFI網卡正在打開
WIFI_STATE_UNKNOWN WIFI網卡狀態不可知
2.要操作WiFi設備,就要使用Context.getSystemService(Context.WIFI_SERVICE)來獲取WifiManager對象,並通過這個對象來管理WiFi設備。
addNetwork(WifiConfiguration config)
添加一個config描述的WIFI網絡,默認情況下,這個WIFI網絡是DISABLE狀態的。
calculateSignalLevel(int rssi , int numLevels)
計算信號的等級
compareSignalLevel(int rssiA, int rssiB)
對比網絡A和網絡B的信號強度
createWifiLock(int lockType, String tag)
創建一個WIFI 鎖,鎖定當前的WIFI連接
disableNetwork(int netId)
讓一個網絡連接失效
disconnect()
斷開當前的WIFI連接
enableNetwork(int netId, Boolean disableOthers)
連接netId所指的WIFI網絡,並是其他的網絡都被禁用
getConfiguredNetworks()
獲取網絡連接的狀態
getConnectionInfo()
獲取當前連接的信息
getDhcpInfo()
獲取DHCP 的信息
getScanResulats()
獲取掃描測試的結果
getWifiState()
獲取當前WIFI設備的狀態
isWifiEnabled()
判斷WIFI設備是否打開
pingSupplicant()
ping操作,和PC的ping操作相同作用
ressociate()
重新連接WIFI網絡,即使該網絡是已經被連接上的
reconnect()
重新連接一個未連接上的WIFI網絡
removeNetwork()
移除某一個網絡
saveConfiguration()
保留一個配置信息
setWifiEnabled()
讓一個連接有效
startScan()
開始掃描
updateNetwork(WifiConfiguration config)
更新一個網絡連接
3.如果要想得到周圍的WIFI熱點列表,可以使用WifiManager.getScanResults()返回一個ScanResult列表,ScanResult對象中,包含了以下幾個屬性:
BSSID 接入點的地址
SSID 網絡的名字,唯一區別WIFI網絡的名字
Capabilities 網絡接入的性能
Frequency 當前WIFI設備附近熱點的頻率(MHz)
Level 所發現的WIFI網絡信號強度
4.連接上自定義的WIFI?
//根據ID值來自動連接WIFI網絡
//@param index ID值
public void ConnectWifiBySSID(int index) {
// 索引大於配置好的網絡索引返回
if (index > mWifiConfiguration.size()) {
return;
}
// 連接配置好的指定ID的網絡
mWifiManager.enableNetwork(mWifiConfiguration.get(index).networkId,true);
}
// 根據WifiConfiguration對象來自動連接WIFI網絡
// @param wcg WifiConfiguration對象
public void ConnectWifiByConfig(WifiConfiguration wifiConfiguration) {
int wcgID = mWifiManager.addNetwork(wifiConfiguration);
mWifiManager.enableNetwork(wcgID, true);
}
5.查看已經連接上的WIFI信息,在Android的SDK中為我們提供了一個叫做WifiInfo的對象,這個對象可以通過WifiManager.getConnectionInfo()來獲取。WifiInfo中包含了當前連接中的相關信息。
getBSSID() 獲取BSSID屬性
getDetailedStateOf() 獲取客戶端的連通性
getHiddenSSID() 獲取SSID 是否被隱藏
getIpAddress() 獲取IP 地址
getLinkSpeed() 獲取連接的速度
getMacAddress() 獲取Mac 地址
getRssi() 獲取802.11n 網絡的信號
getSSID() 獲取SSID
getSupplicanState() 獲取具體客戶端狀態的信息