android wifi(一)

来源:互联网 发布:网络推广日常工作 编辑:程序博客网 时间:2024/04/27 00:39

最近一直在做盒子上的setting,涉及到wifi设置。

android源生的wifi设置代码很复杂,我所工作的项目是在盒子上,不需要那么复杂的功能。

首先注册广播,这一部分直接使用源生的代码,修改了其中的一部分。

private WifiModel(Context context) {mContext = context;mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);mFilter = new IntentFilter();// 注册广播mFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);mFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);mFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION);mFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);mFilter.addAction(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION);mFilter.addAction(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION);mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);mFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);mReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {handleEvent(context, intent);}};mScanner = new Scanner();mContext.registerReceiver(mReceiver, mFilter);}// 处理广播private void handleEvent(Context context, Intent intent) {String action = intent.getAction();Log.i(TAG, action);// wifi状态改变if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {updateWifiState(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN));}// Scanner通过调用mWifiManager.startScan()处理定时扫描wifi列表else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)|| WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION.equals(action)|| WifiManager.LINK_CONFIGURATION_CHANGED_ACTION.equals(action)) {updateAccessPoints();} else if (WifiManager.SUPPLICANT_STATE_CHANGED_ACTION.equals(action)) {// Ignore supplicant state changes when network is connected// TODO: we should deprecate SUPPLICANT_STATE_CHANGED_ACTION and// introduce a broadcast that combines the supplicant and network// network state change events so the apps dont have to worry about// ignoring supplicant state change when network is connected// to get more fine grained information.SupplicantState supplicantState = (SupplicantState) intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE);DetailedState state = WifiInfo.getDetailedStateOf(supplicantState);Log.i(TAG, action + "  " + WifiInfo.getDetailedStateOf(supplicantState) + "  " + mConnected.get() + "  "+ SupplicantState.isHandshakeState(supplicantState) + "  " + isHandshakeState(state));// 本来源生是使用SupplicantState.isHandshakeState(supplicantState)来判断某一wifi连接状态的,// 但是log显示它将DetailedState的DISCONNECTED状态过滤掉了,// 故自己写了一个方法isHandshakeState(state)来判断是否过滤// if (!mConnected.get() &&// SupplicantState.isHandshakeState(supplicantState)) {if (!mConnected.get() && isHandshakeState(state)) {//wifi连接状态更新updateConnectionState(WifiInfo.getDetailedStateOf(supplicantState));}int authState = intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, -1);if (authState == WifiManager.ERROR_AUTHENTICATING) {updateAccessPoints();}}// 网络的连接状态改变else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {NetworkInfo info = (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);mConnected.set(info.isConnected());// if (!(isEthprefer && processWifiEthBothOn()))updateAccessPoints();Log.i(TAG, action + "  " + info.getDetailedState());updateConnectionState(info.getDetailedState());} else if (WifiManager.RSSI_CHANGED_ACTION.equals(action)) {updateConnectionState(null);}}private static boolean isHandshakeState(DetailedState state) {return state != DetailedState.IDLE && state != DetailedState.SCANNING;}


Wifi AP主要分为四种类型 NONE(无密码),WEP加密,PSK(WAP-PSK和WAP2-PSK),EAP(此种wifi网络过滤),获取wifi列表如下,并且已过滤EAP网络。

//此方法是获取wifi列表/** Returns sorted list of access points */private List<AccessPoint> constructAccessPoints() {ArrayList<AccessPoint> accessPoints = new ArrayList<AccessPoint>();/** * Lookup table to more quickly update AccessPoints by only considering * objects with the correct SSID. Maps SSID -> List of AccessPoints with * the given SSID. */Multimap<String, AccessPoint> apMap = new Multimap<String, AccessPoint>();//final List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();if (configs != null) {for (WifiConfiguration config : configs) {AccessPoint accessPoint = new AccessPoint(config);accessPoint.update(mLastInfo, mLastState);accessPoints.add(accessPoint);apMap.put(accessPoint.ssid, accessPoint);}}final List<ScanResult> results = mWifiManager.getScanResults();if (results != null) {for (ScanResult result : results) {// Ignore hidden and ad-hoc networks.// [WPA-EAP-TKIP] : Ignore EAP WIFI.//过滤ssid为空的wifi以及EAP加密网络if (result.SSID == null || result.SSID.length() == 0 || result.capabilities.contains("[IBSS]")|| result.capabilities.contains("[WPA-EAP-TKIP]")) {continue;}boolean found = false;for (AccessPoint accessPoint : apMap.getAll(result.SSID)) {if (accessPoint.update(result))found = true;}if (!found) {AccessPoint accessPoint = new AccessPoint(result);accessPoints.add(accessPoint);apMap.put(accessPoint.ssid, accessPoint);}}}// Pre-sort accessPoints to speed preference insertionCollections.sort(accessPoints);return accessPoints;}

连接网络:分为两种,一种已保存的网络,一种未保存的网络。

已保存网络连接很简单,通过WifiConfiguration的networkId连接即可。

mWifiManager.connect(networkId, l);

未保存的网络,需要先创建一个WifiConfiguration对象,调用mWifiManager.connect(configuration, l);

根据wifi加密方式以及密码来创建WifiConfiguration对象(只有三种,EAP未写出来):

public WifiConfiguration getNewConfig(AccessPoint accessPoint, String password) {if (accessPoint == null) {return null;}if (TextUtils.isEmpty(password) && accessPoint.security != AccessPoint.SECURITY_NONE) {return null;}if (accessPoint.networkId != WifiConfiguration.INVALID_NETWORK_ID) {return null;}WifiConfiguration config = new WifiConfiguration();config.SSID = AccessPoint.convertToQuotedString(accessPoint.ssid);switch (accessPoint.security) {case AccessPoint.SECURITY_NONE:config.allowedKeyManagement.set(KeyMgmt.NONE);break;case AccessPoint.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 AccessPoint.SECURITY_PSK:config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);if (password.matches("[0-9A-Fa-f]{64}")) {config.preSharedKey = password;} else {config.preSharedKey = '"' + password + '"';}break;default:return null;}return config;}

(1)使用很多android hide api,需要在源码下编译或者将源码编译后的classes.jar包导进工程项目中。

(2)WEP加密网络的使用:测试时一直连不上此种类型的网络,是路由器WEP加密网络设置错误,将密码设置后,会生成十位长度的密钥1,此为密码。


下次介绍wifi网络的自动配置以及设置静态ip。

1 0
原创粉丝点击