微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > Android WIFI 详解

Android WIFI 详解

时间:10-08 来源:互联网 点击:

java

public boolean startScan(booleanforceActive) {

enforceChangePermission();

switch (mWifiStateTracker.getSupplicantState()) {

case DISCONNECTED:

case INACTIVE:

case SCANNING:

case DORMANT:

break;

default:

mWifiStateTracker.setScanResultHandling(

WifiStateTracker.SUPPL_SCAN_HANDLING_LIST_ONLY);

break;

}

return mWifiStateTracker.scan(forceActive);

}

然后下面的流程同上面的自动扫描,我们来分析一下手动扫描从哪里开始的。我们应该知道手动扫描是通过菜单键的扫描键来响应的,而响应该动作的应该是 WifiSettings类中Scanner类的handlerMessage()函数,它调用WifiManager的 startScanActive(),这才调用WifiService的startScan()。

packages/apps/Settings/src/com/android/settings/wifiwifisettings.java

public boolean onCreateOptionsMenu(Menu menu) {

menu.add(Menu.NONE, MENU_ID_SCAN, 0, R.string.wifi_menu_scan)

.setIcon(R.drawable.ic_menu_scan_network);

menu.add(Menu.NONE, MENU_ID_ADVANCED, 0, R.string.wifi_menu_advanced)

.setIcon(android.R.drawable.ic_menu_manage);

return super.onCreateOptionsMenu(menu);

}

当按下菜单键时,WifiSettings就会调用这个函数绘制菜单。如果选择扫描按钮,WifiSettings会调用onOptionsItemSelected()。

packages/apps/Settings/src/com/android/settings/wifiwifisettings.java

public booleanonOptionsItemSelected(MenuItem item) {

switch (item.getItemId()) {

case MENU_ID_SCAN:

if(mWifiManager.isWifiEnabled()) {

mScanner.resume();

}

return true;

case MENU_ID_ADVANCED:

startActivity(new Intent(this,AdvancedSettings.class));

return true;

}

return super.onOptionsItemSelected(item);

}

private class Scanner extends Handler {

private int mRetry = 0;

void resume() {

if (!hasMessages(0)) {

sendEmptyMessage(0);

}

}

void pause() {

mRetry = 0;

mAccessPoints.setProgress(false);

removeMessages(0);

}

@Override

public void handleMessage(Message message) {

if (mWifiManager.startScanActive()){

mRetry = 0;

} else if (++mRetry >= 3) {

mRetry = 0;

Toast.makeText(WifiSettings.this, R.string.wifi_fail_to_scan,

Toast.LENGTH_LONG).show();

return;

}

mAccessPoints.setProgress(mRetry != 0);

sendEmptyMessageDelayed(0, 6000);

}

}

这里的mWifiManager.startScanActive()就会调用WifiService里的startScan()函数,下面的流程和上面的一样,这里不赘述。

当supplicant完成了这个扫描命令后,它会发送一个消息给上层,提醒他们扫描已经完成,WifiMonitor会接收到这消息,然后再发送给WifiStateTracker。

Frameworks/base/wifi/java/android/net/wifi/WifiMonitor.java

void handleEvent(int event, String remainder) {

switch (event) {

caseDISCONNECTED:

handleNetworkStateChange(NetworkInfo.DetailedState.DISCONNECTED,remainder);

break;

case CONNECTED:

handleNetworkStateChange(NetworkInfo.DetailedState.CONNECTED,remainder);

break;

case SCAN_RESULTS:

mWifiStateTracker.notifyScanResultsAvailable();

break;

case UNKNOWN:

break;

}

}

WifiStateTracker将会广播SCAN_RESULTS_AVAILABLE_ACTION消息:

Frameworks/base/wifi/java/android/net/wifi/WifiStateTracker.java

public voidhandleMessage(Message msg) {

Intent intent;

……

case EVENT_SCAN_RESULTS_AVAILABLE:

if(ActivityManagerNative.isSystemReady()) {

mContext.sendBroadcast(new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));

}

sendScanResultsAvailable();

/**

* On receiving the first scanresults after connecting to

* the supplicant, switch scanmode over to passive.

*/

setScanMode(false);

break;

……

由于WifiSettings类注册了intent,能够处理SCAN_RESULTS_AVAILABLE_ACTION消息,它会调用handleEvent(),调用流程如下所示。

WifiSettings.handleEvent() =>WifiSettings.updateAccessPoints() => mWifiManager.getScanResults() => mService.getScanResults()=> mWifiStateTracker.scanResults() => WifiNative.scanResultsCommand()……

将获取AP列表的命令发送到supplicant,然后supplicant通过Socket发送扫描结果,由上层接收并显

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top