Android WIFI 配置、連線
阿新 • • 發佈:2018-12-31
在RK3188板卡上實現Wifi配置與連線,在網上搜索了一些資料瞭解到wifi連線流程,下面是從第一次刷機後的連線wifi流程
1、判斷wifi是否啟動如果沒啟動則開啟wifi
2、掃描wifi根據要連線的wifi名稱檢索出想要的掃描結果
3、掃描結果判斷該名稱wifi的加密型別
4、根據wifi加密型別建立wifi配置
5、將wifi配置新增都wiifi配置列表,得到該配置的唯一ID;這部很重要
6、根據得到的配置ID進行連線wifi
先貼出自己實現的一個Wifi輔助類
package com.midea.test.factory.wifi; import java.util.List; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiConfiguration.AuthAlgorithm; import android.net.wifi.WifiConfiguration.KeyMgmt; import android.net.wifi.WifiManager; public class WifiHelper { public static final int SECURITY_NONE = 0; public static final int SECURITY_WEP = 1; public static final int SECURITY_PSK = 2; // WPA、WPA2、WPA_WPA2 public static final int SECURITY_EAP = 3; public static void startScan(Context context){ WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); manager.startScan(); } public static List<ScanResult> getScanResults(Context context){ WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); return manager.getScanResults(); } public static boolean isWifiOpen(Context context){ WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); return manager.isWifiEnabled(); } public static void setWifiEnabled(Context context,boolean isEnabled){ WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); manager.setWifiEnabled(isEnabled); //是否開啟需監聽廣播 WIFI_STATE_CHANGED_ACTION } public static int updateWifiConfiguration(Context context,WifiConfiguration configuration){ WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); return manager.updateNetwork(configuration); } public static boolean isWifiConnected(Context context) { ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo[] networkInfos = connectivityManager.getAllNetworkInfo(); if(networkInfos == null){ return false; } for(int i =0; i < networkInfos.length; i ++){ if(networkInfos[i].getState()== NetworkInfo.State.CONNECTED){ return true; } } return false ; } public static WifiConfiguration checkWifiConfiguration(Context context,String ssid){ WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); List<WifiConfiguration> configurations = manager.getConfiguredNetworks(); if(configurations == null){ return null; } for(WifiConfiguration configuration :configurations){ if(configuration.SSID.equals(ssid)){ return configuration; } } return null; } public static int getSecurity(ScanResult result) { if (result.capabilities.contains("WEP")) { return SECURITY_WEP; } else if (result.capabilities.contains("PSK")) { return SECURITY_PSK; } else if (result.capabilities.contains("EAP")) { return SECURITY_EAP; } return SECURITY_NONE; } public static String convertToQuotedString(String string) { return "\"" + string + "\""; } //from com.android.settings.wifi.WifiConfigController /** * 這裡直接是閱讀系統設定裡面的wifi配置 * 其實這裡可以閱讀以下WifiConfiguration,裡面關於wifi的加密引數 * @param accessPointSecurity * @param ssid * @param password * @return */ public static WifiConfiguration getConfig(int accessPointSecurity, String ssid, String password) { WifiConfiguration config = new WifiConfiguration(); config.SSID = convertToQuotedString(ssid); config.hiddenSSID = true; switch (accessPointSecurity) { case SECURITY_NONE: config.allowedKeyManagement.set(KeyMgmt.NONE); break; case SECURITY_WEP: config.allowedKeyManagement.set(KeyMgmt.NONE); config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN); config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED); int length = password.length(); // WEP-40, WEP-104, and 256-bit WEP (WEP-232?) if ((length == 10 || length == 26 || length == 58) && password.matches("[0-9A-Fa-f]*")) { config.wepKeys[0] = password; } else { config.wepKeys[0] = '"' + password + '"'; } break; case SECURITY_PSK: config.allowedKeyManagement.set(KeyMgmt.WPA_PSK); if (password.length() != 0) { if (password.matches("[0-9A-Fa-f]{64}")) { config.preSharedKey = password; } else { config.preSharedKey = '"' + password + '"'; } } break; case SECURITY_EAP: //EAP暫時還沒不完整 config.allowedKeyManagement.set(KeyMgmt.WPA_EAP); config.allowedKeyManagement.set(KeyMgmt.IEEE8021X); break; default: return null; } return config; } public static int addWifiConfiguration(Context context,WifiConfiguration configuration){ WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); return manager.addNetwork(configuration); } public static void connectWifi(Context context,int networkId){ WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); manager.enableNetwork(networkId, true); } }
下面程式碼是實現 搜尋 配置 連線的過程。主要流程是
1、如果沒開啟Wifi就開啟Wifi,然後在廣播“WifiManager.WIFI_STATE_CHANGED_ACTION”去掃描wifi熱點(當然這裡不夠嚴格,應該還要判斷wifi狀態是否可用);
如果wifi是開啟狀態就直接掃描,掃描wifi會觸發“WifiManager.NETWORK_STATE_CHANGED_ACTION”廣播,在這個廣播裡面獲取WifiInfo後可以判斷要連線的wifi名稱是否存在,如果存在則WIFI是已經連線的。
2、啟動掃描後不是立即返回掃描列表的,可以看看API解釋
英語不好就用有道翻譯一下Request a scan for access points. Returns immediately. The availability of the results is made knownlater by means of an asynchronous event sent on completion of the scan.主要看到這個幾個紅字便可知道非同步返回,需要監聽廣播“WifiManager.SCAN_RESULTS_AVAILABLE_ACTION”/** * Request a scan for access points. Returns immediately. The availability * of the results is made known later by means of an asynchronous event sent * on completion of the scan. * @return {@code true} if the operation succeeded, i.e., the scan was initiated */ public boolean startScan() { try { final WorkSource workSource = null; mService.startScan(workSource); return true; } catch (RemoteException e) { return false; } }
3、掃描列表出來後需要或者要連線的wifi加密方式,以下是摘自系統設定的程式碼
其實這裡的PSK是包含WPA、WPA2、WPA_WPA2三種加密方式(可以閱讀系統設定的WifiConfigController.java)public static int getSecurity(ScanResult result) { if (result.capabilities.contains("WEP")) { return SECURITY_WEP; } else if (result.capabilities.contains("PSK")) { return SECURITY_PSK; } else if (result.capabilities.contains("EAP")) { return SECURITY_EAP; } return SECURITY_NONE; }
4、得到要連線wifi的加密方式後這時需建立wifi配置,程式碼如下也是摘自系統設定的
//from com.android.settings.wifi.WifiConfigController
/**
* 這裡直接是閱讀系統設定裡面的wifi配置
* 其實這裡可以閱讀以下WifiConfiguration,裡面關於wifi的加密引數
* @param accessPointSecurity
* @param ssid
* @param password
* @return
*/
public static WifiConfiguration getConfig(int accessPointSecurity, String ssid,
String password) {
WifiConfiguration config = new WifiConfiguration();
config.SSID = convertToQuotedString(ssid);
config.hiddenSSID = true;
switch (accessPointSecurity) {
case SECURITY_NONE:
config.allowedKeyManagement.set(KeyMgmt.NONE);
break;
case SECURITY_WEP:
config.allowedKeyManagement.set(KeyMgmt.NONE);
config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);
int length = password.length();
// WEP-40, WEP-104, and 256-bit WEP (WEP-232?)
if ((length == 10 || length == 26 || length == 58)
&& password.matches("[0-9A-Fa-f]*")) {
config.wepKeys[0] = password;
} else {
config.wepKeys[0] = '"' + password + '"';
}
break;
case SECURITY_PSK:
config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
if (password.length() != 0) {
if (password.matches("[0-9A-Fa-f]{64}")) {
config.preSharedKey = password;
} else {
config.preSharedKey = '"' + password + '"';
}
}
break;
case SECURITY_EAP:
//EAP暫時還沒不完整
config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
break;
default:
return null;
}
return config;
}
5、配置好後需要新增到wifi配置列表得到配置的id
manager.addNetwork(configuration);
6、通過配置的ID提交連線,連線的過程也是非同步的,需要監聽廣播“WifiManager.NETWORK_STATE_CHANGED_ACTION”,在這個廣播裡面獲取WifiInfo後可以判斷要連線的wifi名稱是否存在,如果存在則WIFI是已經連線的。
以上只是大概的流程,還需嚴格控制。