(1)ConnectivityManager
在Android中,ConnectivityManager類代表網絡連接服務,它被用來監控網絡連接狀態,配置失效重連,並控制網絡天線等。獲取Connectivity Manager實例的方法是使用getSystemService,並指定Context.CONNECTIVITY_SERVICE作爲參數,代碼片段如下:
- String cserviceName = Context.CONNECTIVITY_SERVICE;
- ConnectivityManager cm = (ConnectivityManager) getSystemService(cserviceName);
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
- <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
Connectivity Manager在較高層面提供了管理可用網絡連接的接口,使用getActiveNetworkInfo和getNetworkInfo函數可以查詢獲取NetworkInfo對象,該對象包含了當前活動網絡連接或者指定類型的不可用網絡連接的詳細信息。
1.1)設置首選網絡
當任何認證的應用程序請求網絡連接時,Android都會優先嚐試使用首選網絡連接。設置首選網絡連接的函數是setNetworkPreference,代碼片段如下:
- cm.setNetworkPreference(ConnectivityManager.TYPE_WIFI);
當首選網絡連接不可用或者連接丟失時,Android將自動嘗試使用第二優先連接類型。
1.2)監控網絡連接
ConnectivityManager最常用的一個功能就是當網絡連接狀態改變時通知應用程序,這是通過應用程序實現自己的Broadcast Receiver來監聽ConnectivityManager.CONNECTIVITY_ACTION類型的intent來實現的。這個intent提供了以下幾種extra來進一步明確發生改變的網絡狀態:
1)ConnectivityManager.EXTRA_IS_FAILOVER:值爲true說明當前的連接是首選網絡失效重連後的連接;
2)ConnectivityManager.EXTRA_NO_CONNECTIVITY:值爲true表示當前設備沒有連接到網絡;
3)ConnectivityManager.EXTRA_REASON:如果當前的廣播代表網絡失效,則這個值包含了連接失效的原因描述;
4)ConnectivityManager.EXTRA_NETWORK_INFO:返回NetworkInfo對象,包含了當前連接事件相關的網絡詳細信息;
5)ConnectivityManager.EXTRA_OTHER_NETWORK_INFO:在一個網絡斷開連接時,這個值返回NetworkInfo對象,包含了可能的網絡失效重連的詳細信息;
6)ConnectivityManager.EXTRA_EXTRA_INFO:包含可選的網絡連接的額外信息。
(2)WifiManager
WifiManager代表Android中的Wi-Fi連接服務,它被用於配置Wi-Fi網絡連接,管理當前Wi-Fi連接,掃描Wi-Fi接入點和監控Wi-Fi連接的狀態改變。獲取WifiManager的方法和Connectivity Manager類似,通過函數getSystemService,並提供參數Context.WIFI_SERVICE,代碼片段如下:
- String wserviceName = Context.WIFI_SERVICE;
- WifiManager wm = (WifiManager) getSystemService(wserviceName);
同樣的,需要在AndroidManifest.xml文件中指定訪問許可:
- <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
- <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
我們可以使用setWifiEnabled函數來設置使能和去使能Wi-Fi硬件,使用getWifiState和isWifiEnabled函數來查看當前Wi-Fi狀態,代碼片段如下:
- if (!wm.isWifiEnabled()) {
- if (WifiManager.WIFI_STATE_ENABLING != wm.getWifiState()) {
- wm.setWifiEnabled(true);
- }
- }
2.1)監控Wi-Fi連接
在Wi-Fi網絡連接狀態改變時,Wi-Fi Manager將廣播相應的intent,有如下幾種:
1)WifiManager.WIFI_STATE_CHANGED_ACTION:標識Wi-Fi硬件狀態改變,可能在enabling、enabled、disabling、disabled和unknown之間改變。它包含了兩個額外的鍵值EXTRA_WIFI_STATE和EXTRA_PREVIOUS_STATE,分別表示新的和前一個Wi-Fi狀態。
2)WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION:Wi-Fi硬件和當前接入點之間的連接狀態改變時,這個intent將被廣播。額外的鍵值EXTRA_NEW_STATE用來表示是新的連接建立事件還是已存在的連接中斷事件,爲true表示新的連接建立。
3)WifiManager.NETWORK_STATE_CHANGED_ACTION:Wi-Fi連接狀態改變時廣播這個intent,包含兩個額外的鍵值:一是EXTRA_NETWORK_INFO,它包含表示當前網絡狀態的NetworkInfo對象;一是EXTRA_BSSID,包含連接到的接入點的BSSID值。
4)WifiManager.RSSI_CHANGED_ACTION:監聽這個intent可以使應用程序監控當前Wi-Fi連接的信號強度。包含一個額外鍵值EXTRA_NEW_RSSI,包含了當前信號強度。使用這個信號強度,需要使用靜態函數calculateSignalLevel將這個值按指定的縮放轉換爲整型值。
2.2)創建和管理Wi-Fi連接和配置
使用WiFi Manager可以進行網絡配置,控制連接到哪個網絡。當連接建立後,可以進一步獲取活動網絡連接的額外配置信息。使用函數getConfiguredNetworks可獲得當前網絡配置信息的列表,返回值是WifiConfiguration對象,包含了網絡ID、SSID和其他配置信息。
要使用某一網絡連接,可使用enableNetwork函數,傳入網絡ID並設置disableAllOthers參數爲true即可,代碼片段如下:
- // Get a list of available configurations
- List<WifiConfiguration> configurations = wm.getConfiguredNetworks();
- // Get the network ID for the first one
- if (configurations.size() > 0) {
- int netID = configurations.get(0).networkId;
- // Enable the network
- boolean disableAllOthers = true;
- wm.enableNetwork(netID, disableAllOthers);
- }
一旦連接建立,就可以使用getConnectionInfo函數來返回連接的狀態,返回的是WifiInfo對象,包含了當前接入點的BSSID、Mac地址、IP地址,以及當前鏈路速度和信號強度。
下面的代碼片段用於查詢當前活動Wi-Fi連接並顯示獲取的相關信息:
- WifiInfo info = wm.getConnectionInfo();
- if (null != info.getBSSID()) {
- int strength = WifiManager.calculateSignalLevel(info.getRssi(), 5);
- int speed = info.getLinkSpeed();
- String units = WifiInfo.LINK_SPEED_UNITS;
- String ssid = info.getSSID();
- String toastText = String.format("Connected to {0} at {1}{2}. Strength {3}/5", ssid, speed, units, strength);
- Toast.makeText(this.getApplicationContext(), toastText, Toast.LENGTH_LONG);
- }
2.3)掃描Wifi熱點
我們可以使用startScan函數進行Wifi接入點的掃描,當掃描結束且結果可用時,WifiManager將發送SCAN_RESULTS_AVAILABLE_ACTIONL類型的intent。使用getScanResults函數可以獲取掃描的結果信息,並保存中ScanResult對象中。ScanResult對象中存放了檢測到的每個接入點的詳細信息,包括鏈路速度、信號強度、SSID和支持的認證技術。下面代碼片段顯示了Wifi熱點掃描的過程:
- // Register a broadcast receiver that listens for scan results
- registerReceiver(new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- List<ScanResult> results = wifi.getScanResults();
- ScanResult bestSignal = null;
- for (ScanResult result : results) {
- if (null == bestSignal ||
- WifiManager.compareSignalLevel(bestSignal.level, result.level) < 0) {
- bestSignal = result;
- }
- }
- String toastText = String.format("{0} networks found. {1} is the strongest.",
- results.size(), bestSignal.SSID);
- Toast.makeText(getApplicationContext(), toastText, Toast.LENGTH_LONG);
- }
- }, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
- //Initiate a scan
- wifi.startScan();
要連接到網絡,需要創建和註冊WiFi配置,通常用戶可以使用Android系統原生的WiFi配置程序,但我們也可以在自己的應用程序中提供相同的功能,設置完全替代原生的WiFi配置程序,這就要用到保存網絡配置信息的WifiConfiguration類了。每個WiFi配置一般都會包含以下幾個公共的數據項:
1)BSSID:指明接入點的BSSID;
2)SSID:某一特定網絡的SSID;
3)networkId:用來唯一標識當前設備使用的網絡配置的id;
4)priority:選擇連接哪個接入點時要使用的每個網絡配置的優先權;
5)status:當前網絡連接的狀態,取值如下:
WifiConfiguration.Status.ENABLED,WifiConfiguration.Status.DISABLED,
WifiConfiguration.Status.CURRENT。
WifiConfiguration對象中還包括支持的認證技術以及用於與接入點進行認證的密鑰。
使用addNetwork函數可以將新的WiFi配置添加到當前WiFi列表中,類似的,updateNetwork函數可以用於更新某個已存在的WiFi配置的某些信息;removeNetwork函數用於移除配置信息。要保存網絡配置的任何變化,需要調用saveConfiguration函數。