首页 > 代码库 > WifiSettings源码分析一

WifiSettings源码分析一

wifi的入口Activity:WifiSettings.java

进入wifi界面首先显示的是wifi关闭的页面(wifi默认关闭)
技术分享
接着打开开关,开始扫面附近可用热点

技术分享

搜索到热点就以列表的形式显示出来,我们可对可用的wifi进行连接、保存、添加、删除等操作。

那么这一系列的动作在代码中是如何体现出来的呢?看代码分析,。

1、onCreate()

@Override
public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    //设置布局文件
    addPreferencesFromResource(R.xml.wifi_settings);
    mUserBadgeCache = new UserBadgeCache(getPackageManager());

    //启动线程
    mBgThread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND);
    mBgThread.start();
}

2、onActivityCreated()

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    //创建wifitracker对象,设置扫描到wifi后系统发送的广播的action
    mWifiTracker =
            new WifiTracker(getActivity(), this, mBgThread.getLooper(), true, true, false);
    //获取wifi管理器,管理wifi的开启、关闭、扫描、建立连接、配置等信息
    mWifiManager = mWifiTracker.getManager();
    //wifi连接监听
    mConnectListener = new WifiManager.ActionListener() {
                               @Override
                               public void onSuccess() {
                               }
                               @Override
                               public void onFailure(int reason) {
                                   Activity activity = getActivity();
                                   if (activity != null) {
                                       Toast.makeText(activity,
                                            R.string.wifi_failed_connect_message,
                                            Toast.LENGTH_SHORT).show();
                                   }
                               }
                           };
    //wifi保存监听(右上角menu:Saved Networks)
    mSaveListener = new WifiManager.ActionListener() {
                            @Override
                            public void onSuccess() {
                            }
                            @Override
                            public void onFailure(int reason) {
                                Activity activity = getActivity();
                                if (activity != null) {
                                    Toast.makeText(activity,
                                        R.string.wifi_failed_save_message,
                                        Toast.LENGTH_SHORT).show();
                                }
                            }
                        };
    //忘记网络监听
    mForgetListener = new WifiManager.ActionListener() {
                               @Override
                               public void onSuccess() {
                               }
                               @Override
                               public void onFailure(int reason) {
                                   Activity activity = getActivity();
                                   if (activity != null) {
                                       Toast.makeText(activity,
                                           R.string.wifi_failed_forget_message,
                                           Toast.LENGTH_SHORT).show();
                                   }
                               }
                           };

    if (savedInstanceState != null) {
        mDlgEdit = savedInstanceState.getBoolean(SAVE_DIALOG_EDIT_MODE);
        mDlgModify = savedInstanceState.getBoolean(SAVE_DIALOG_MODIFY_MODE);
        if (savedInstanceState.containsKey(SAVE_DIALOG_ACCESS_POINT_STATE)) {
            mAccessPointSavedState =
                savedInstanceState.getBundle(SAVE_DIALOG_ACCESS_POINT_STATE);
        }

        if (savedInstanceState.containsKey(SAVED_WIFI_NFC_DIALOG_STATE)) {
            mWifiNfcDialogSavedState =
                savedInstanceState.getBundle(SAVED_WIFI_NFC_DIALOG_STATE);
        }
    }

    // if we‘re supposed to enable/disable the Next button based on our current connection
    // state, start it off in the right state
    Intent intent = getActivity().getIntent();
    mEnableNextOnConnection = intent.getBooleanExtra(EXTRA_ENABLE_NEXT_ON_CONNECT, false);

    if (mEnableNextOnConnection) {
        if (hasNextButton()) {
            final ConnectivityManager connectivity = (ConnectivityManager)
                    getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
            if (connectivity != null) {
                NetworkInfo info = connectivity.getNetworkInfo(
                        ConnectivityManager.TYPE_WIFI);
                changeNextButtonState(info.isConnected());
            }
        }
    }

    //初始化空的视图
    mEmptyView = initEmptyView();
    //注册上下文菜单(相当于ListView的长按事件)
    registerForContextMenu(getListView());
    //在Fragment中给action bar添加action在onCreate()中调用 setHasOptionsMenu(true)。Android Framework会调用Fragement中的onCreateOptionsMenu()来向Activity的Menu中添加item。
    setHasOptionsMenu(true);

    if (intent.hasExtra(EXTRA_START_CONNECT_SSID)) {
        mOpenSsid = intent.getStringExtra(EXTRA_START_CONNECT_SSID);
        onAccessPointsChanged();
    }
}

在OnActivityCreate()函数中首先是创建了WifiTracker对象,经过分析发现这个类是负责启动wifi扫描附近可用热点的类,在启动扫描前进行了广播动作的设置。但还木有真正的注册广播接收者。

@VisibleForTesting
WifiTracker(Context context, WifiListener wifiListener, Looper workerLooper,
        boolean includeSaved, boolean includeScans, boolean includePasspoints,
        WifiManager wifiManager, Looper currentLooper) {
    if (!includeSaved && !includeScans) {
        throw new IllegalArgumentException("Must include either saved or scans");
    }
    mContext = context;
    if (currentLooper == null) {
        // When we aren‘t on a looper thread, default to the main.
        currentLooper = Looper.getMainLooper();
    }
    mMainHandler = new MainHandler(currentLooper);
    mWorkHandler = new WorkHandler(
            workerLooper != null ? workerLooper : currentLooper);
    mWifiManager = wifiManager;
    mIncludeSaved = includeSaved;
    mIncludeScans = includeScans;
    mIncludePasspoints = includePasspoints;
    mListener = wifiListener;

    // check if verbose logging has 
    //检查已打开或关闭的详细日志记录
    been turned on or off
    sVerboseLogging = mWifiManager.getVerboseLoggingLevel();

    mFilter = new IntentFilter();
    //wifi状态改变(wifi打开、关闭等改变时会发送广播)
    mFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
    //扫描结束时发送的广播
    mFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
    //网络ID改变
    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);
    //Received Signal Strength Indication接收的信号强度指示;无线发送层的可选部分;用来判定链接质量;以及是否增大广播发送强度。
    //信号强度改变
    mFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);
}

创建mMainHandler

private final class MainHandler extends Handler {
    private static final int MSG_CONNECTED_CHANGED = 0;
    private static final int MSG_WIFI_STATE_CHANGED = 1;
    private static final int MSG_ACCESS_POINT_CHANGED = 2;
    private static final int MSG_RESUME_SCANNING = 3;
    private static final int MSG_PAUSE_SCANNING = 4;

    public MainHandler(Looper looper) {
        super(looper);
    }

    @Override
    public void handleMessage(Message msg) {
        if (mListener == null) {
            return;
        }
        switch (msg.what) {
            //连接状态发生变化
            case MSG_CONNECTED_CHANGED:
                mListener.onConnectedChanged();
                break;
            //WiFi状态发生变化
            case MSG_WIFI_STATE_CHANGED:
                mListener.onWifiStateChanged(msg.arg1);
                break;
            //接入点发生变化
            case MSG_ACCESS_POINT_CHANGED:
                mListener.onAccessPointsChanged();
                break;
            //扫描开始,扫描附近可用wifi
            case MSG_RESUME_SCANNING:
                if (mScanner != null) {
                    mScanner.resume();
                }
                break;
            //扫描暂停
            case MSG_PAUSE_SCANNING:
                if (mScanner != null) {
                    mScanner.pause();
                }
                break;
        }
    }
}

创建WorkHandler

private final class WorkHandler extends Handler {
    private static final int MSG_UPDATE_ACCESS_POINTS = 0;
    private static final int MSG_UPDATE_NETWORK_INFO = 1;
    private static final int MSG_RESUME = 2;

    public WorkHandler(Looper looper) {
        super(looper);
    }

    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            //更新接入点
            case MSG_UPDATE_ACCESS_POINTS:
                updateAccessPoints();
                break;
            //更新网络信息
            case MSG_UPDATE_NETWORK_INFO:
                updateNetworkInfo((NetworkInfo) msg.obj);
                break;
            case MSG_RESUME:
                //清空扫描的结果缓存集合、接入点地址、id。
                handleResume();
                break;
        }
    }
}

3、onViewCreate()

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    final Activity activity = getActivity();
    if (activity != null) {
        mProgressHeader = (ProgressBar) setPinnedHeaderView(R.layout.wifi_progress_header);
    }
}

4、onStart()

@Override
public void onStart() {
    super.onStart();
    // On/off switch is hidden for Setup Wizard (returns null)
    mWifiEnabler = createWifiEnabler();
}

WifiEnabler.java这个类是负责wifi开关(SwitchBar)的设置,监听SwitchBar的状态:打开、正在打开、正在关闭、关闭等状态并随着状态的改变更新UI。

WifiSettings.java调用createWifiEnabler(),创建WifiEnabler对象。

 /**
 * @return new WifiEnabler or null (as overridden by WifiSettingsForSetupWizard)
 */
/* package */ WifiEnabler createWifiEnabler() {
    final SettingsActivity activity = (SettingsActivity) getActivity();
    return new WifiEnabler(activity, activity.getSwitchBar());
}

WifiEnabler.java的构造方法:

public WifiEnabler(Context context, SwitchBar switchBar) {
    mContext = context;
    mSwitchBar = switchBar;

    mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);

    mIntentFilter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION);
    // The order matters! We really should not depend on this. :(
    mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
    mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);

    setupSwitchBar();
}

从代码中可以看出这里取得了Wifi管理器,注册广播监听wifi状态、网络状态的变化,创建了SwitchBar开关。

public void setupSwitchBar() {
    //获得wifi state
    final int state = mWifiManager.getWifiState();
    //根据wifi state 设置switchbar的打开或关闭。
    handleWifiStateChanged(state);
    if (!mListeningToOnSwitchChange) {
        mSwitchBar.addOnSwitchChangeListener(this);
        mListeningToOnSwitchChange = true;
    }
    //显示开关
    mSwitchBar.show();
}

取出wifi的状态,根据wifi的状态来设置SwitchBar,给SwitchBar注册监听器,监听开关的变化。

private void handleWifiStateChanged(int state) {
    switch (state) {
        //wifi正在打开
        case WifiManager.WIFI_STATE_ENABLING:
            mSwitchBar.setEnabled(false);
            break;
        //wifi已经打开
        case WifiManager.WIFI_STATE_ENABLED:
            setSwitchBarChecked(true);
            mSwitchBar.setEnabled(true);
            updateSearchIndex(true);
            break;
        //wifi正在关闭
        case WifiManager.WIFI_STATE_DISABLING:
            mSwitchBar.setEnabled(false);
            break;
        //wifi已经关闭
        case WifiManager.WIFI_STATE_DISABLED:
            setSwitchBarChecked(false);
            mSwitchBar.setEnabled(true);
            updateSearchIndex(false);
            break;
        default:
            setSwitchBarChecked(false);
            mSwitchBar.setEnabled(true);
            updateSearchIndex(false);
    }
}

updateSearchIndex()

private void updateSearchIndex(boolean isWiFiOn) {
    mHandler.removeMessages(EVENT_UPDATE_INDEX);

    Message msg = new Message();
    msg.what = EVENT_UPDATE_INDEX;
    msg.getData().putBoolean(EVENT_DATA_IS_WIFI_ON, isWiFiOn);
    mHandler.sendMessage(msg);
}

private Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case EVENT_UPDATE_INDEX:
                //取出wifi打开或关闭的标识
                final boolean isWiFiOn = msg.getData().getBoolean(EVENT_DATA_IS_WIFI_ON);

                Index.getInstance(mContext).updateFromClassNameResource(
                        WifiSettings.class.getName(), true, isWiFiOn);
                break;
        }
    }
};

5、onResume()

在onStart()函数中SwitchBar已经初始化好了,UI界面也按照SwitchBar的状态显示了,那么可以开始根据SwitchBar的开关状态来决定是否启动wifi扫描附近可用的热点。接下来一步一步分析具体点过程。

@Override
public void onResume() {
    final Activity activity = getActivity();
    super.onResume();
    //Needed so PreferenceGroupAdapter allows AccessPointPreference to be
         recycled. Removed in onResume 
    removePreference("dummy");
    if (mWifiEnabler != null) {
        mWifiEnabler.resume(activity);
    }

    mWifiTracker.startTracking();
}

5.1、首先,判断wifienable是否为空,如果不为空则调用WifiEnabler.java的resume()函数。

public void resume(Context context) {
    mContext = context;
    // Wi-Fi state is sticky, so just let the receiver update UI
    mContext.registerReceiver(mReceiver, mIntentFilter);
    if (!mListeningToOnSwitchChange) {
        mSwitchBar.addOnSwitchChangeListener(this);
        mListeningToOnSwitchChange = true;
    }
}

5.2、其次,注册广播接收者,这个就是在WifiEnabler.java在构造方法中准备的系统发送的广播就被注册了。用于接收系统发送的关于wifi、网络状态的变化的信息。

private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        //wifi状态改变
        if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
            handleWifiStateChanged(intent.getIntExtra(
                    WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN));
        } 
        //正在创建连接状态发生变化
        else if (WifiManager.SUPPLICANT_STATE_CHANGED_ACTION.equals(action)) {
            if (!mConnected.get()) {
                handleStateChanged(WifiInfo.getDetailedStateOf((SupplicantState)
                        intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE)));
            }
        }
        //网络状态发生变化
        else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
            NetworkInfo info = (NetworkInfo) intent.getParcelableExtra(
                    WifiManager.EXTRA_NETWORK_INFO);
            mConnected.set(info.isConnected());
            handleStateChanged(info.getDetailedState());
        }
    }
};

状态发生改变时调用的更新方法

private void handleStateChanged(@SuppressWarnings("unused") NetworkInfo.DetailedState state) {
    // After the refactoring from a CheckBoxPreference to a Switch, this method is useless since
    // there is nowhere to display a summary.
    // This code is kept in case a future change re-introduces an associated text.
    /*
    // WifiInfo is valid if and only if Wi-Fi is enabled.
    // Here we use the state of the switch as an optimization.
    if (state != null && mSwitch.isChecked()) {
        WifiInfo info = mWifiManager.getConnectionInfo();
        if (info != null) {
            //setSummary(Summary.get(mContext, info.getSSID(), state));
        }
    }
    */
}

这个方法已经被注释掉,那就不做分析了。

5.3、接着是给SwitchBar添加监听事件,监听开关的状态。开关被触发回调onSwitchChanged()函数

@Override
public void onSwitchChanged(Switch switchView, boolean isChecked) {
    //Do nothing if called as a result of a state machine event
    if (mStateMachineEvent) {
        return;
    }

    //提示在飞行模式下wifi不能打开
    if (isChecked && !WirelessUtils.isRadioAllowed(mContext, Settings.Global.RADIO_WIFI)) {
        Toast.makeText(mContext, R.string.wifi_in_airplane_mode, Toast.LENGTH_SHORT).show();
        // Reset switch to off. No infinite check/listenenr loop.
        mSwitchBar.setChecked(false);
        return;
    }

    // Disable tethering if enabling Wifi
    //如果wifi正在打开禁止热点共享
    int wifiApState = mWifiManager.getWifiApState();
    if (isChecked && ((wifiApState == WifiManager.WIFI_AP_STATE_ENABLING) ||
            (wifiApState == WifiManager.WIFI_AP_STATE_ENABLED))) {
        //调用WifiManager的方法实际上是继续调用了WifiService.java类的setWifiApEnabled()方法关闭热点
        mWifiManager.setWifiApEnabled(null, false);
    }
    MetricsLogger.action(mContext,
            isChecked ? MetricsLogger.ACTION_WIFI_ON : MetricsLogger.ACTION_WIFI_OFF);
    if (!mWifiManager.setWifiEnabled(isChecked)) {
        // Error
        mSwitchBar.setEnabled(true);
        Toast.makeText(mContext, R.string.wifi_error, Toast.LENGTH_SHORT).show();
    }
}

5.4、最后调用了WifiTracker.java的startTracking()函数。那就到WifiTracker.java中分析扫描到显示的过程。

/**
 * Start tracking wifi networks.
 * Registers listeners and starts scanning for wifi networks. If this is not called
 * then forceUpdate() must be called to populate getAccessPoints().
 */
public void startTracking() {
    resumeScanning();
    if (!mRegistered) {
        mContext.registerReceiver(mReceiver, mFilter);
        mRegistered = true;
    }
}

5.4.1、当扫描暂停时,重新恢复扫描状态,扫描可用wifi

/**
 * Resume scanning for wifi networks after it has been paused.
 */
public void resumeScanning() {
    //判断如果扫描器对象为空,则创建新的扫描器对象
    if (mScanner == null) {
        mScanner = new Scanner();
    }

    mWorkHandler.sendEmptyMessage(WorkHandler.MSG_RESUME);
    //判断wifi是否打开
    if (mWifiManager.isWifiEnabled()) {
        //SwitchBar打开则开始扫描附近可用wifi
        mScanner.resume();
    }
    mWorkHandler.sendEmptyMessage(WorkHandler.MSG_UPDATE_ACCESS_POINTS);
}

WorkHandler.MSG_RESUME:清空扫描结果缓存的集合、接入点地址集合、id

private void handleResume() {
    mScanResultCache.clear();
    //接入点地址
    mSeenBssids.clear();
    mScanId = 0;
}

Scanner.resmue()启动扫描,发送消息

@Override
public void handleMessage(Message message) {
    if (message.what != MSG_SCAN) return;
    if (mWifiManager.startScan()) {
        mRetry = 0;
    } else if (++mRetry >= 3) {//如果扫描次数操过三次,提示扫描失败,停止扫描
        mRetry = 0;
        if (mContext != null) {
            Toast.makeText(mContext, R.string.wifi_fail_to_scan, Toast.LENGTH_LONG).show();
        }
        return;
    }
    //每隔10秒,发起扫描的操作
    sendEmptyMessageDelayed(0, WIFI_RESCAN_INTERVAL_MS);
}

WorkHandler.MSG_UPDATE_ACCESS_POINTS:扫描到可用wifi后就更新接入点,把扫描到的接入点缓存到列表中

private void updateAccessPoints() {
    // Swap the current access points into a cached list.
    //获取当前接入点列表
    List<AccessPoint> cachedAccessPoints = getAccessPoints();
    ArrayList<AccessPoint> accessPoints = new ArrayList<>();

    /** 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>();
    WifiConfiguration connectionConfig = null;
    if (mLastInfo != null) {
        //获取wifi配置的网络id
        connectionConfig = getWifiConfigurationForNetworkId(mLastInfo.getNetworkId());
    }

    final List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
    //抓取扫描结果返回一个扫描结果集合。
    final Collection<ScanResult> results = fetchScanResults();

    // Clear out the configs so we don‘t think something is saved when it isn‘t.
    //清空缓存的接入点列表
    for (AccessPoint accessPoint : cachedAccessPoints) {
        accessPoint.clearConfig();
    }
    //如果wifi配置
    if (configs != null) {
        mSavedNetworksExist = configs.size() != 0;
        for (WifiConfiguration config : configs) {
            if (config.selfAdded && config.numAssociation == 0) {
                continue;
            }
            AccessPoint accessPoint = getCachedOrCreate(config, cachedAccessPoints);
            if (mLastInfo != null && mLastNetworkInfo != null) {
                if (config.isPasspoint() == false) {
                    accessPoint.update(connectionConfig, mLastInfo, mLastNetworkInfo);
                }
            } else {
                accessPoint.update(config);
            }
            if (mIncludeSaved) {
                if (!config.isPasspoint() || mIncludePasspoints)
                    accessPoints.add(accessPoint);

                if (config.isPasspoint() == false) {
                    apMap.put(accessPoint.getSsidStr(), accessPoint);

                    if (results != null) {
                        boolean inScanResults = false;
                        for (ScanResult result : results) {
                            if (accessPoint.matches(result)) {
                                inScanResults = true;
                                break;
                            }
                        }
                        if (!inScanResults) { // If the ap is not in scan results, clear its rssi
                            accessPoint.clearRssi();
                        }
                    }
                }
            } else {
                // If we aren‘t using saved networks, drop them into the cache so that
                // we have access to their saved info.
                cachedAccessPoints.add(accessPoint);
            }
        }
    }

    if (results != null) {
        for (ScanResult result : results) {
            // Ignore hidden and ad-hoc networks.
            if (result.SSID == null || result.SSID.length() == 0 ||
                    result.capabilities.contains("[IBSS]")) {
                continue;
            }

            boolean found = false;
            for (AccessPoint accessPoint : apMap.getAll(result.SSID)) {
                if (accessPoint.update(result)) {
                    found = true;
                    break;
                }
            }
            if (!found && mIncludeScans) {
                AccessPoint accessPoint = getCachedOrCreate(result, cachedAccessPoints);
                if (mLastInfo != null && mLastNetworkInfo != null) {
                    accessPoint.update(connectionConfig, mLastInfo, mLastNetworkInfo);
                }

                if (result.isPasspointNetwork()) {
                    WifiConfiguration config = mWifiManager.getMatchingWifiConfig(result);
                    if (config != null) {
                        accessPoint.update(config);
                    }
                }

                if (mLastInfo != null && mLastInfo.getBSSID() != null
                        && mLastInfo.getBSSID().equals(result.BSSID)
                        && connectionConfig != null && connectionConfig.isPasspoint()) {
                    /* This network is connected via this passpoint config */
                    /* SSID match is not going to work for it; so update explicitly */
                    accessPoint.update(connectionConfig);
                }

                accessPoints.add(accessPoint);
                apMap.put(accessPoint.getSsidStr(), accessPoint);
            }
        }
    }

    // Pre-sort accessPoints to speed preference insertion
    Collections.sort(accessPoints);

    // Log accesspoints that were deleted
    if (DBG) { // Code is useful only when DBG is true.
        Log.d(TAG, "------ Dumping SSIDs that were not seen on this scan ------");
        for (AccessPoint prevAccessPoint : mAccessPoints) {
            if (prevAccessPoint.getSsid() == null) continue;
            String prevSsid = prevAccessPoint.getSsidStr();
            boolean found = false;
            for (AccessPoint newAccessPoint : accessPoints) {
                if (newAccessPoint.getSsid() != null && newAccessPoint.getSsid().equals(prevSsid)) {
                    found = true;
                    break;
                }
            }
            if (!found)
                if (DBG) Log.d(TAG, "Did not find " + prevSsid + " in this scan");
        }
        Log.d(TAG, "---- Done dumping SSIDs that were not seen on this scan ----");
    }

    mAccessPoints = accessPoints;
    mMainHandler.sendEmptyMessage(MainHandler.MSG_ACCESS_POINT_CHANGED);
}

5.4.2、mContext.registerReceiver(mReceiver, mFilter);注册广播接收者,接收发送的wifi相关的信息。

@VisibleForTesting
final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        //wifi状态改变时更新wifi状态
        if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
            updateWifiState(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
                    WifiManager.WIFI_STATE_UNKNOWN));
        } 
        //扫描结果、网络配置(当WiFi列表中的网络添加、更新或者删除)、连接参数发生变化时,更新接入点列表。
        else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action) ||
                WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION.equals(action) ||
                WifiManager.LINK_CONFIGURATION_CHANGED_ACTION.equals(action)) {
            mWorkHandler.sendEmptyMessage(WorkHandler.MSG_UPDATE_ACCESS_POINTS);
        }
        //网络状态发生变化时
        else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
            //获取网络信息
            NetworkInfo info = (NetworkInfo) intent.getParcelableExtra(
                    WifiManager.EXTRA_NETWORK_INFO);
            //设置连接状态
            mConnected.set(info.isConnected());
            //通知连接状态发生改变,回调onConnectedChanged()
            mMainHandler.sendEmptyMessage(MainHandler.MSG_CONNECTED_CHANGED);

            //通知更新接入点列表
            mWorkHandler.sendEmptyMessage(WorkHandler.MSG_UPDATE_ACCESS_POINTS);
            //通知更新网络信息
            mWorkHandler.obtainMessage(WorkHandler.MSG_UPDATE_NETWORK_INFO, info)
                    .sendToTarget();
        } 
        //wifi信号强度发生改变
        else if (WifiManager.RSSI_CHANGED_ACTION.equals(action)) {
            //通知更新网络信息。
            mWorkHandler.sendEmptyMessage(WorkHandler.MSG_UPDATE_NETWORK_INFO);
        }
    }
};
<script type="text/javascript"> $(function () { $(‘pre.prettyprint code‘).each(function () { var lines = $(this).text().split(‘\n‘).length; var $numbering = $(‘
    ‘).addClass(‘pre-numbering‘).hide(); $(this).addClass(‘has-numbering‘).parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($(‘
  • ‘).text(i)); }; $numbering.fadeIn(1700); }); }); </script>

    WifiSettings源码分析一