Android WiFi 扫描和连接热点

本章主要介绍用户手动的在Settings中点击Scan和Connect按钮,输入密码后的连接过程,先看整体流程图:


WiFi Scan过程分析

当用户进入Settings点击Scan后,就会调用到WifiManager的startScan()方法,当然在Settings里面有设置Scan的定时器,每隔一段时间就会去scan,在Wifi Framework中也有scan的定时器。对照上面的流程图,来看一下WifiManager的startScan()方法:

    public boolean startScan(WorkSource workSource) {
        try {
            mService.startScan(workSource);
            return true;
        } catch (RemoteException e) {
            return false;
        }
    }

WifiService.java
    public void startScan(WorkSource workSource) {
        enforceChangePermission();
        if (workSource != null) {
            enforceWorkSourcePermission();
            // WifiManager currently doesn't use names, so need to clear names out of the
            // supplied WorkSource to allow future WorkSource combining.
            workSource.clearNames();
        }
        mWifiStateMachine.startScan(Binder.getCallingUid(), workSource);
    }

WiFiStateMachine的startScan方法会给自己发送一个CMD_START_SCAN的message,由前面toggle on wifi的知识,这个消息将由DisconnectedState及其父State来处理,从代码中可以很容易的分析到,CMD_START_SCAN将会被DriverStartedState 来处理,进入到处理的代码中:

        public boolean processMessage(Message message) {
            switch(message.what) {
                case CMD_START_SCAN:
                    noteScanStart(message.arg1, (WorkSource) message.obj);
                    startScanNative(WifiNative.SCAN_WITH_CONNECTION_SETUP);
                    break;

noteScanStart是用于通知电量统计用;startScanNative会向wpa_supplicant发送SCAN的命令,当wpa_suppliant执行完SCAN并成功找到一些AP后,就会给WifiMonitor发送CTRL-EVENT-SCAN-RESULTS的event,WifiMonitor会parse出这个event,并向WifiStateMachine发送SCAN_RESULTS_EVENT消息,WifiStateMachine的SupplicantStartedState会处理这个消息,如下:

                case WifiMonitor.SCAN_RESULTS_EVENT:
                    setScanResults();
                    sendScanResultsAvailableBroadcast();
                    mScanResultIsPending = false;
                    break;

这里主要做了两件事,一是去获取scanResults,另外会发送一个广播信息出去,如果有检测这个广播的receive收到这个广播后,就可以调用函数去获取到scanResults并显示到listview上面,例如WifiSettings。进入到setScanResults里面来分析:

    private void setScanResults() {

        while (true) {
            tmpResults = mWifiNative.scanResults(sid);
            if (TextUtils.isEmpty(tmpResults)) break;
            scanResultsBuf.append(tmpResults);
            scanResultsBuf.append("\n");
            String[] lines = tmpResults.split("\n");
            sid = -1;
            for (int i=lines.length - 1; i >= 0; i--) {
                if (lines[i].startsWith(END_STR)) {
                    break;
                } else if (lines[i].startsWith(ID_STR)) {
                    try {
                        sid = Integer.parseInt(lines[i].substring(ID_STR.length())) + 1;
                    } catch (NumberFormatException e) {
                        // Nothing to do
                    }
                    break;
                }
            }
            if (sid == -1) break;
        }

        scanResults = scanResultsBuf.toString();
        if (TextUtils.isEmpty(scanResults)) {
           return;
        }

        synchronized(mScanResultCache) {

            for (String line : lines) {
                if (line.startsWith(BSSID_STR)) {
                    bssid = new String(line.getBytes(), bssidStrLen, line.length() - bssidStrLen);
                } else if (line.startsWith(FREQ_STR)
  • 0
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值