在设置界面上,进入wifi选项,点击使能按键,设备开始扫描AP,更新AP 、选择AP后,弹出界面来配置AP,连接AP ,获取到IP地址,可以联网了。

WifiSettings调用类示意图如下:

rk3288 android6.0 wifi子系统 - Settings 联网

 

1. wifi使能

 

WifiSettings.java

public void onStart() {
        super.onStart();

        // On/off switch is hidden for Setup Wizard (returns null)
        mWifiEnabler = createWifiEnabler();
    }

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

WifiEnabler和Switch 对象被创建。 看WifiEnabler函数, 进入WifiEnabler.java, 代码如下:

 

public class WifiEnabler implements SwitchBar.OnSwitchChangeListener  {
   ......

private final IntentFilter mIntentFilter;

private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
      
public void onReceive(Context context, Intent intent) {
            String action
= intent.getAction();
          
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());
            }
        }
    };

   ......

  
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();
    }

   ......

  
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;
        }
    }

   ......
}

 

mIntentFilter是个广播, 可以看到这里, 用了三条广播, WIFI_STATE_CHANGED_ACTION, SUPPLICANT_STATE_CHANGED_ACTION, NETWORK_STATE_CHANGED_ACTION.

private void handleWifiStateChanged(int state) {
        switch (state) {
            case WifiManager.WIFI_STATE_ENABLING:
                mSwitchBar.setEnabled(false);
                break;
            case WifiManager.WIFI_STATE_ENABLED:
                setSwitchBarChecked(true);
                mSwitchBar.setEnabled(true);
                updateSearchIndex(true);
                break;
            case WifiManager.WIFI_STATE_DISABLING:
                mSwitchBar.setEnabled(false);
                break;
            case WifiManager.WIFI_STATE_DISABLED:
                setSwitchBarChecked(false);
                mSwitchBar.setEnabled(true);
                updateSearchIndex(false);
                break;
            default:
                setSwitchBarChecked(false);
                mSwitchBar.setEnabled(true);
                updateSearchIndex(false);
        }
    }

当Wi-Fi功能被启用时,将收到WIFI_STATE_CHANGED_ACTION广播. 接下来开始扫描AP

 

2. 扫描AP

 

进入 WifiSettings.java

 

void resumeWifiScan() {
        mWifiTracker.resumeScanning();
    }

 

WifiTracker.java

public void resumeScanning() {
        if (mScanner == null) {
            mScanner = new Scanner();
        }

        mWorkHandler.sendEmptyMessage(WorkHandler.MSG_RESUME);
        if (mWifiManager.isWifiEnabled()) {
            mScanner.resume();
        }
        mWorkHandler.sendEmptyMessage(WorkHandler.MSG_UPDATE_ACCESS_POINTS);
    }

发送消息MSG_UPDATE_ACCESS_POINTS, 开始更新AP

 

 

3. 更新AP

 

WifiTracker.java

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:
                    handleResume();
                    break;
            }
        }



    private void updateAccessPoints() {
        // Swap the current access points into a cached list.
        List<AccessPoint> cachedAccessPoints = getAccessPoints();
        ArrayList<AccessPoint> accessPoints = new ArrayList<>();

        // Clear out the configs so we don't think something is saved when it isn't.
        for (AccessPoint accessPoint : cachedAccessPoints) {
            accessPoint.clearConfig();
        }

        /** 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) {
            connectionConfig = getWifiConfigurationForNetworkId(mLastInfo.getNetworkId());
        }

        final List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
        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);
                    }
                }
                if (mIncludeSaved) {
                    if (!config.isPasspoint() || mIncludePasspoints){
                        //sid.bao add for reset saved network's rssi.
                        accessPoint.resetRssi();
                        accessPoints.add(accessPoint);
                    }

                    if (config.isPasspoint() == false) {
                        apMap.put(accessPoint.getSsidStr(), accessPoint);
                    }
                } 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);
                }
            }
        }

        final Collection<ScanResult> results = fetchScanResults();
        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) 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");
        }
        if (DBG)  Log.d(TAG, "---- Done dumping SSIDs that were not seen on this scan ----");

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

 

MSG_ACCESS_POINT_CHANGED 进入到 onAccessPointsChanged

/**
     * Shows the latest access points available with supplemental information like
     * the strength of network and the security for it.
     */
    @Override
    public void onAccessPointsChanged() {
        // Safeguard from some delayed event handling
        if (getActivity() == null) return;

        if (isUiRestricted()) {
            addMessagePreference(R.string.wifi_empty_list_user_restricted);
            return;
        }
        final int wifiState = mWifiManager.getWifiState();

        switch (wifiState) {
            case WifiManager.WIFI_STATE_ENABLED:
                // AccessPoints are automatically sorted with TreeSet.
                final Collection<AccessPoint> accessPoints =
                        mWifiTracker.getAccessPoints();
                getPreferenceScreen().removeAll();

                boolean hasAvailableAccessPoints = false;
                int index = 0;
                for (AccessPoint accessPoint : accessPoints) {
                    // Ignore access points that are out of range.
                    if (accessPoint.getLevel() != -1) {
                        hasAvailableAccessPoints = true;
                        if (accessPoint.getTag() != null) {
                            final Preference pref = (Preference) accessPoint.getTag();
                            pref.setOrder(index++);
                            getPreferenceScreen().addPreference(pref);
                            continue;
                        }
                        AccessPointPreference preference = new AccessPointPreference(accessPoint,
                                getActivity(), mUserBadgeCache, false);
                        preference.setOrder(index++);

                        if (mOpenSsid != null && mOpenSsid.equals(accessPoint.getSsidStr())
                                && !accessPoint.isSaved()
                                && accessPoint.getSecurity() != AccessPoint.SECURITY_NONE) {
                            onPreferenceTreeClick(getPreferenceScreen(), preference);
                            mOpenSsid = null;
                        }
                        getPreferenceScreen().addPreference(preference);
                        accessPoint.setListener(this);
                    }
                }
                if (!hasAvailableAccessPoints) {
                    setProgressBarVisible(true);
                    addMessagePreference(R.string.wifi_empty_list_wifi_on);
                } else {
                    setProgressBarVisible(false);
                }
                break;

            case WifiManager.WIFI_STATE_ENABLING:
                getPreferenceScreen().removeAll();
                setProgressBarVisible(true);
                break;

            case WifiManager.WIFI_STATE_DISABLING:
                addMessagePreference(R.string.wifi_stopping);
                setProgressBarVisible(true);
                break;

            case WifiManager.WIFI_STATE_DISABLED:
                setOffMessage();
                setProgressBarVisible(false);
                break;
        }
        // Update "Saved Networks" menu option.
        if (savedNetworksExist != mWifiTracker.doSavedNetworksExist()) {
            savedNetworksExist = !savedNetworksExist;
            getActivity().invalidateOptionsMenu();
        }
    }

 

 

4. 配置AP

 

选择用到的AP,弹出的界面,开始配置密码等消息。

 

 

@Override
    public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {
        if (preference instanceof AccessPointPreference) {
            mSelectedAccessPoint = ((AccessPointPreference) preference).getAccessPoint();
            /** Bypass dialog for unsecured, unsaved, and inactive networks */
            if (mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_NONE &&
                    !mSelectedAccessPoint.isSaved() && !mSelectedAccessPoint.isActive()) {
                mSelectedAccessPoint.generateOpenNetworkConfig();
                if (!savedNetworksExist) {
                    savedNetworksExist = true;
                    getActivity().invalidateOptionsMenu();
                }
                connect(mSelectedAccessPoint.getConfig());
            } else if (mSelectedAccessPoint.isSaved()){
                mDlgModify = false;
                showDialog(mSelectedAccessPoint, false);
            } else {
                mDlgModify = false;
                showDialog(mSelectedAccessPoint, true);
            }
        } else {
            return super.onPreferenceTreeClick(screen, preference);
        }
        return true;
    }

    private void showDialog(AccessPoint accessPoint, boolean edit) {
        if (accessPoint != null) {
            WifiConfiguration config = accessPoint.getConfig();
            if (isEditabilityLockedDown(getActivity(), config) && accessPoint.isActive()) {
                final int userId = UserHandle.getUserId(config.creatorUid);
                final PackageManager pm = getActivity().getPackageManager();
                final IPackageManager ipm = AppGlobals.getPackageManager();
                String appName = pm.getNameForUid(config.creatorUid);
                try {
                    final ApplicationInfo appInfo = ipm.getApplicationInfo(appName, /* flags */ 0,
                            userId);
                    final CharSequence label = pm.getApplicationLabel(appInfo);
                    if (label != null) {
                        appName = label.toString();
                    }
                } catch (RemoteException e) {
                    // leave appName as packageName
                }
                final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
                builder.setTitle(accessPoint.getSsid())
                        .setMessage(getString(R.string.wifi_alert_lockdown_by_device_owner,
                                appName))
                        .setPositiveButton(android.R.string.ok, null)
                        .show();
                return;
            }
        }

        if (mDialog != null) {
            removeDialog(WIFI_DIALOG_ID);
            mDialog = null;
        }

        // Save the access point and edit mode
        mDlgAccessPoint = accessPoint;
        mDlgEdit = edit;

        showDialog(WIFI_DIALOG_ID);
    }

当设置完后, 点击【连接】按键, 设备开始连接AP,获取IP。

 

5. 联网

 

/* package */ void submit(WifiConfigController configController) {

        final WifiConfiguration config = configController.getConfig();

        if (config == null) {
            if (mSelectedAccessPoint != null
                    && mSelectedAccessPoint.isSaved()) {
                connect(mSelectedAccessPoint.getConfig());
            }
        } else if (configController.isModify()) {
            mWifiManager.save(config, mSaveListener);
        } else {
            mWifiManager.save(config, mSaveListener);
            if (mSelectedAccessPoint != null) { // Not an "Add network"
                connect(config);
            }
        }

        mWifiTracker.resumeScanning();
    }

判断config, 如果是配置, 保持并连接目标AP

protected void connect(final WifiConfiguration config) {
        MetricsLogger.action(getActivity(), MetricsLogger.ACTION_WIFI_CONNECT);
        mWifiManager.connect(config, mConnectListener);
    }
从这里可以看出,又跳跃到了WifiManager

 

进入WifiManager.java

public void connect(WifiConfiguration config, ActionListener listener) {
        if (config == null) throw new IllegalArgumentException("config cannot be null");
        validateChannel();
        // Use INVALID_NETWORK_ID for arg1 when passing a config object
        // arg1 is used to pass network id when the network already exists
        sAsyncChannel.sendMessage(CONNECT_NETWORK, WifiConfiguration.INVALID_NETWORK_ID,
                putListener(listener), config);
    }

看到了熟悉的sAsyncChannel

相关文章:

  • 2021-08-20
  • 2021-11-10
  • 2021-11-17
  • 2022-01-09
  • 2021-12-29
  • 2021-07-31
  • 2021-12-25
  • 2021-06-02
猜你喜欢
  • 2021-06-14
  • 2021-11-04
  • 2021-08-12
  • 2021-07-02
  • 2021-05-12
  • 2022-01-13
  • 2021-12-27
相关资源
相似解决方案