Android WiFi 打开关闭流程

本文简单介绍下WiFi打开与关闭流程,参考源码Android P

一、WiFi 开机自动打开流程

系统服务启动的时候会启动WifiService,在SystemService.PHASE_SYSTEM_SERVICES_READY的时候,会调用 WifiServiceImpl#checkAndStartWifi(),获取Wi-Fi开关,持久化存储的值。

然后判断是否需要打开WiFi。

    /**
     * Check if we are ready to start wifi.
     *
     * First check if we will be restarting system services to decrypt the device. If the device is
     * not encrypted, check if Wi-Fi needs to be enabled and start if needed
     *
     * This function is used only at boot time.
     */
    public void checkAndStartWifi() {
        // First check if we will end up restarting WifiService
        if (mFrameworkFacade.inStorageManagerCryptKeeperBounce()) {
            Log.d(TAG, "Device still encrypted. Need to restart SystemServer.  Do not start wifi.");
            return;
        }

        // Check if wi-fi needs to be enabled
        boolean wifiEnabled = mSettingsStore.isWifiToggleEnabled();
        ........

        // If we are already disabled (could be due to airplane mode), avoid changing persist
        // state here
        if (wifiEnabled) {
            try {
                setWifiEnabled(mContext.getPackageName(), wifiEnabled);
            } catch (RemoteException e) {
                /* ignore - local call */
            }
        }
    }

二、系统设置主动开启WiFi

1. WiFi开关切换,在WifiEnabler的SwitchToggled中会调用WifiManager.setWifiEnabled方法。

    @Override
    public boolean onSwitchToggled(boolean isChecked) {
        //Do nothing if called as a result of a state machine event
        if (mStateMachineEvent) {
            return true;
        }
        // Show toast message if Wi-Fi is not allowed in airplane mode
        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/listener loop.
            mSwitchWidget.setChecked(false);
            return false;
        }

        if (isChecked) {
            mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_WIFI_ON);
        } else {
            // Log if user was connected at the time of switching off.
            mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_WIFI_OFF,
                    mConnected.get());
        }
        if (!mWifiManager.setWifiEnabled(isChecked)) {
            // Error
            mSwitchWidget.setEnabled(true);
            Toast.makeText(mContext, R.string.wifi_error, Toast.LENGTH_SHORT).show();
        }
        return true;
    }

2. WifiManager中通过AIDL接口调用WifiService的方法。

    /**
     * Enable or disable Wi-Fi.
     * <p>
     * Applications must have the {@link android.Manifest.permission#CHANGE_WIFI_STATE}
     * permission to toggle wifi.
     *
     * @param enabled {@code true} to enable, {@code false} to disable.
     * @return {@code false} if the request cannot be satisfied; {@code true} indicates that wifi is
     *         either already in the requested state, or in progress toward the requested state.
     * @throws  {@link java.lang.SecurityException} if the caller is missing required permissions.
     */
    public boolean setWifiEnabled(boolean enabled) {
        try {
            return mService.setWifiEnabled(mContext.getOpPackageName(), enabled);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

3. WiFiManager.aidl中提供了setWifiEnabled()接口。

boolean setWifiEnabled(String packageName, boolean enable);

4. WifiServiceImpl中实现WifiManager的接口,在setWifiEnabled函数中会先调用WifiSettingsStore将WiFi开关值进行持久化存储。

然后WifiController发消息CMD_WIFI_TOGGLED 去打开WiFi。

    /**
     * see {@link android.net.wifi.WifiManager#setWifiEnabled(boolean)}
     * @param enable {@code true} to enable, {@code false} to disable.
     * @return {@code true} if the enable/disable operation was
     *         started or is already in the queue.
     */
    @Override
    public synchronized boolean setWifiEnabled(String packageName, boolean enable)
            throws RemoteException {
        ........

        try {
            if (! mSettingsStore.handleWifiToggled(enable)) {
                // Nothing to do if wifi cannot be toggled
                return true;
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
        ........

        mWifiController.sendMessage(CMD_WIFI_TOGGLED);
        return true;
    }

5. WifiController中对CMD_WIFI_TOGGLED消息进行处理,从初始状态StaDisabledState(如果没有开启wifi_scan_always_enabled功能)切换到DeviceActiveState状态。

    class StaDisabledState extends State {
        private int mDeferredEnableSerialNumber = 0;
        private boolean mHaveDeferredEnable = false;
        private long mDisabledTimestamp;

        @Override
        public void enter() {
            mWifiStateMachinePrime.disableWifi();
            // Supplicant can't restart right away, so note the time we switched off
            mDisabledTimestamp = SystemClock.elapsedRealtime();
            mDeferredEnableSerialNumber++;
            mHaveDeferredEnable = false;
            mWifiStateMachine.clearANQPCache();
        }
        @Override
        public boolean processMessage(Message msg) {
            switch (msg.what) {
                case CMD_WIFI_TOGGLED:
                    if (mSettingsStore.isWifiToggleEnabled()) {
                        if (doDeferEnable(msg)) {
                            if (mHaveDeferredEnable) {
                                //  have 2 toggles now, inc serial number and ignore both
                                mDeferredEnableSerialNumber++;
                            }
                            mHaveDeferredEnable = !mHaveDeferredEnable;
                            break;
                        }
                        transitionTo(mDeviceActiveState);
                    } else if (checkScanOnlyModeAvailable()) {
                        // only go to scan mode if we aren't in airplane mode
                        if (mSettingsStore.isAirplaneModeOn()) {
                            transitionTo(mStaDisabledWithScanState);
                        }
                    }
                    break;
        ........
        }
    }

    /**
     * Parent: StaEnabledState
     *
     * TODO (b/79209870): merge DeviceActiveState and StaEnabledState into a single state
     */
    class DeviceActiveState extends State {
        @Override
        public void enter() {
            mWifiStateMachinePrime.enterClientMode();
            mWifiStateMachine.setHighPerfModeEnabled(false);
        }

        @Override
        public boolean processMessage(Message msg) {
            if (msg.what == CMD_USER_PRESENT) {
                // TLS networks can't connect until user unlocks keystore. KeyStore
                // unlocks when the user punches PIN after the reboot. So use this
                // trigger to get those networks connected.
                if (mFirstUserSignOnSeen == false) {
                    mWifiStateMachine.reloadTlsNetworksAndReconnect();
                }
                mFirstUserSignOnSeen = true;
                return HANDLED;
            } else if (msg.what == CMD_RECOVERY_RESTART_WIFI) {
                final String bugTitle;
                final String bugDetail;
                if (msg.arg1 < SelfRecovery.REASON_STRINGS.length && msg.arg1 >= 0) {
                    bugDetail = SelfRecovery.REASON_STRINGS[msg.arg1];
                    bugTitle = "Wi-Fi BugReport: " + bugDetail;
                } else {
                    bugDetail = "";
                    bugTitle = "Wi-Fi BugReport";
                }
                if (msg.arg1 != SelfRecovery.REASON_LAST_RESORT_WATCHDOG) {
                    (new Handler(mWifiStateMachineLooper)).post(() -> {
                        mWifiStateMachine.takeBugReport(bugTitle, bugDetail);
                    });
                }
                return NOT_HANDLED;
            }
            return NOT_HANDLED;
        }
    }

进入DeviceActiveState,执行enter()函数,执行enterClientMode,给ModeStateMachine状态机发送CMD_START_CLIENT_MODE消息。

    /**
     * Method to switch wifi into client mode where connections to configured networks will be
     * attempted.
     */
    public void enterClientMode() {
        changeMode(ModeStateMachine.CMD_START_CLIENT_MODE);
    }


    private class ModeStateMachine extends StateMachine {
        ........
        private boolean checkForAndHandleModeChange(Message message) {
            switch(message.what) {
                case ModeStateMachine.CMD_START_CLIENT_MODE:
                    Log.d(TAG, "Switching from " + getCurrentMode() + " to ClientMode");
                    mModeStateMachine.transitionTo(mClientModeActiveState);
                    break;
                case ModeStateMachine.CMD_START_SCAN_ONLY_MODE:
                    Log.d(TAG, "Switching from " + getCurrentMode() + " to ScanOnlyMode");
                    mModeStateMachine.transitionTo(mScanOnlyModeActiveState);
                    break;
                case ModeStateMachine.CMD_DISABLE_WIFI:
                    Log.d(TAG, "Switching from " + getCurrentMode() + " to WifiDisabled");
                    mModeStateMachine.transitionTo(mWifiDisabledState);
                    break;
                default:
                    return NOT_HANDLED;
            }
            return HANDLED;
        }
        ........
    }

6. 进入ClientModeActiveState,执行enter()函数,WifiInjector创建一个 ClientModeManager,并start。

    class ClientModeActiveState extends ModeActiveState {
            @Override
            public void enter() {
                Log.d(TAG, "Entering ClientModeActiveState");

                mListener = new ClientListener();
                mManager = mWifiInjector.makeClientModeManager(mListener);
                mManager.start();
                mActiveModeManagers.add(mManager);

                updateBatteryStatsWifiState(true);
            }
    }

    /**
     * Create a ClientModeManager
     *
     * @param listener listener for ClientModeManager state changes
     * @return a new instance of ClientModeManager
     */
    public ClientModeManager makeClientModeManager(ClientModeManager.Listener listener) {
        return new ClientModeManager(mContext, mWifiStateMachineHandlerThread.getLooper(),
                mWifiNative, listener, mWifiMetrics, mScanRequestProxy, mWifiStateMachine);
    }

ClientModeManager 中去启动客户端模式,发送消息CMD_START,进去到IdleState继续处理,处理完毕进入StartedState。

    /**
     * Start client mode.
     */
    public void start() {
        mStateMachine.sendMessage(ClientModeStateMachine.CMD_START);
    }
        private class IdleState extends State {

            @Override
            public void enter() {
                Log.d(TAG, "entering IdleState");
                mClientInterfaceName = null;
                mIfaceIsUp = false;
            }

            @Override
            public boolean processMessage(Message message) {
                switch (message.what) {
                    case CMD_START:
                        updateWifiState(WifiManager.WIFI_STATE_ENABLING,
                                        WifiManager.WIFI_STATE_DISABLED);

                        mClientInterfaceName = mWifiNative.setupInterfaceForClientMode(
                                false /* not low priority */, mWifiNativeInterfaceCallback);
                        if (TextUtils.isEmpty(mClientInterfaceName)) {
                            Log.e(TAG, "Failed to create ClientInterface. Sit in Idle");
                            updateWifiState(WifiManager.WIFI_STATE_UNKNOWN,
                                            WifiManager.WIFI_STATE_ENABLING);
                            updateWifiState(WifiManager.WIFI_STATE_DISABLED,
                                            WifiManager.WIFI_STATE_UNKNOWN);
                            break;
                        }
                        sendScanAvailableBroadcast(false);
                        mScanRequestProxy.enableScanningForHiddenNetworks(false);
                        mScanRequestProxy.clearScanResults();
                        transitionTo(mStartedState);
                        break;
                    default:
                        Log.d(TAG, "received an invalid message: " + message);
                        return NOT_HANDLED;
                }
                return HANDLED;
            }
        }

7. 接下来看下WifiNative 中setupInterfaceForClientMode,在其中做了HAL部分的启动(包含check驱动是否已经准备ok,HAL部分是否成功启动),之后再进行wpa_supplicant进程的启动,状态检测进程的启动startMonitoring。

    /**
     * Setup an interface for Client mode operations.
     *
     * This method configures an interface in STA mode in all the native daemons
     * (wificond, wpa_supplicant & vendor HAL).
     *
     * @param lowPrioritySta The requested STA has a low request priority (lower probability of
     *                       getting created, higher probability of getting destroyed).
     * @param interfaceCallback Associated callback for notifying status changes for the iface.
     * @return Returns the name of the allocated interface, will be null on failure.
     */
    public String setupInterfaceForClientMode(boolean lowPrioritySta,
            @NonNull InterfaceCallback interfaceCallback) {
        synchronized (mLock) {
            if (!startHal()) {
                Log.e(TAG, "Failed to start Hal");
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
                return null;
            }
            if (!startSupplicant()) {
                Log.e(TAG, "Failed to start supplicant");
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
                return null;
            }
            Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_STA);
            if (iface == null) {
                Log.e(TAG, "Failed to allocate new STA iface");
                return null;
            }
            iface.externalListener = interfaceCallback;
            iface.name = createStaIface(iface, lowPrioritySta);
            if (TextUtils.isEmpty(iface.name)) {
                Log.e(TAG, "Failed to create STA iface in vendor HAL");
                mIfaceMgr.removeIface(iface.id);
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
                return null;
            }
            if (mWificondControl.setupInterfaceForClientMode(iface.name) == null) {
                Log.e(TAG, "Failed to setup iface in wificond on " + iface);
                teardownInterface(iface.name);
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToWificond();
                return null;
            }
            if (!mSupplicantStaIfaceHal.setupIface(iface.name)) {
                Log.e(TAG, "Failed to setup iface in supplicant on " + iface);
                teardownInterface(iface.name);
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
                return null;
            }
            iface.networkObserver = new NetworkObserverInternal(iface.id);
            if (!registerNetworkObserver(iface.networkObserver)) {
                Log.e(TAG, "Failed to register network observer on " + iface);
                teardownInterface(iface.name);
                return null;
            }
            mWifiMonitor.startMonitoring(iface.name);
            // Just to avoid any race conditions with interface state change callbacks,
            // update the interface state before we exit.
            onInterfaceStateChanged(iface, isInterfaceUp(iface.name));
            initializeNwParamsForClientInterface(iface.name);
            Log.i(TAG, "Successfully setup " + iface);
            return iface.name;
        }
    }

8. 在ClientModeManager中进行状态的更新,广播WiFi状态改变消息。

    /**
     * Update Wifi state and send the broadcast.
     * @param newState new Wifi state
     * @param currentState current wifi state
     */
    private void updateWifiState(int newState, int currentState) {
        if (!mExpectedStop) {
            mListener.onStateChanged(newState);
        } else {
            Log.d(TAG, "expected stop, not triggering callbacks: newState = " + newState);
        }

        // Once we report the mode has stopped/failed any other stop signals are redundant
        // note: this can happen in failure modes where we get multiple callbacks as underlying
        // components/interface stops or the underlying interface is destroyed in cleanup
        if (newState == WifiManager.WIFI_STATE_UNKNOWN
                || newState == WifiManager.WIFI_STATE_DISABLED) {
            mExpectedStop = true;
        }

        if (newState == WifiManager.WIFI_STATE_UNKNOWN) {
            // do not need to broadcast failure to system
            return;
        }

        mWifiStateMachine.setWifiStateForApiCalls(newState);

        final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
        intent.putExtra(WifiManager.EXTRA_WIFI_STATE, newState);
        intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE, currentState);
        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
    }

9. 系统设置在WifiEnabler中会监听WiFi的状态。

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

三、WiFi关闭流程

与打开流程一样,只是在WifiController中收到CMD_WIFI_TOGGLED消息,会从StaEnabledState切换到mStaDisabledState(如果没有启用wifi_scan_always_enabled功能)。

    class StaDisabledState extends State {
        private int mDeferredEnableSerialNumber = 0;
        private boolean mHaveDeferredEnable = false;
        private long mDisabledTimestamp;

        @Override
        public void enter() {
            mWifiStateMachinePrime.disableWifi();
            // Supplicant can't restart right away, so note the time we switched off
            mDisabledTimestamp = SystemClock.elapsedRealtime();
            mDeferredEnableSerialNumber++;
            mHaveDeferredEnable = false;
            mWifiStateMachine.clearANQPCache();
        }

会调用WifiStateMachinePrime.disableWifi() 发送消息CMD_DISABLE_WIFI 。

    /**
     * Method to disable wifi in sta/client mode scenarios.
     *
     * This mode will stop any client/scan modes and will not perform any network scans.
     */
    public void disableWifi() {
        changeMode(ModeStateMachine.CMD_DISABLE_WIFI);
    }

WifiStateMachinePrime中则会由ClientModeActiveState切换到WifiDisabled,会执行ClientModeActiveState的exit()函数,其调用ModeActiveState的exit(),调用mManager.stop(),最终会将wifi最新状态设置到WifiStateMachine。

        class ModeActiveState extends State {
            ActiveModeManager mManager;
            @Override
            public boolean processMessage(Message message) {
                // handle messages for changing modes here
                return NOT_HANDLED;
            }

            @Override
            public void exit() {
                // Active states must have a mode manager, so this should not be null, but it isn't
                // obvious from the structure - add a null check here, just in case this is missed
                // in the future
                if (mManager != null) {
                    mManager.stop();
                    mActiveModeManagers.remove(mManager);
                }
                updateBatteryStatsWifiState(false);
            }
        }
        private boolean checkForAndHandleModeChange(Message message) {
            switch(message.what) {
                case ModeStateMachine.CMD_START_CLIENT_MODE:
                    Log.d(TAG, "Switching from " + getCurrentMode() + " to ClientMode");
                    mModeStateMachine.transitionTo(mClientModeActiveState);
                    break;
                case ModeStateMachine.CMD_START_SCAN_ONLY_MODE:
                    Log.d(TAG, "Switching from " + getCurrentMode() + " to ScanOnlyMode");
                    mModeStateMachine.transitionTo(mScanOnlyModeActiveState);
                    break;
                case ModeStateMachine.CMD_DISABLE_WIFI:
                    Log.d(TAG, "Switching from " + getCurrentMode() + " to WifiDisabled");
                    mModeStateMachine.transitionTo(mWifiDisabledState);
                    break;
                default:
                    return NOT_HANDLED;
            }
            return HANDLED;
        }

ClientModeManager中也会从StartedState切换到IdleState,在启exit()函数中调用mWifiNative.teardownInterface

        private class StartedState extends State {

            private void onUpChanged(boolean isUp) {
                if (isUp == mIfaceIsUp) {
                    return;  // no change
                }
                mIfaceIsUp = isUp;
                if (isUp) {
                    Log.d(TAG, "Wifi is ready to use for client mode");
                    sendScanAvailableBroadcast(true);
                    mWifiStateMachine.setOperationalMode(WifiStateMachine.CONNECT_MODE,
                                                         mClientInterfaceName);
                    updateWifiState(WifiManager.WIFI_STATE_ENABLED,
                                    WifiManager.WIFI_STATE_ENABLING);
                } else {
                    if (mWifiStateMachine.isConnectedMacRandomizationEnabled()) {
                        // Handle the error case where our underlying interface went down if we
                        // do not have mac randomization enabled (b/72459123).
                        return;
                    }
                    // if the interface goes down we should exit and go back to idle state.
                    Log.d(TAG, "interface down!");
                    updateWifiState(WifiManager.WIFI_STATE_UNKNOWN,
                                    WifiManager.WIFI_STATE_ENABLED);
                    mStateMachine.sendMessage(CMD_INTERFACE_DOWN);
                }
            }

            /**
             * Clean up state, unregister listeners and update wifi state.
             */
            @Override
            public void exit() {
                mWifiStateMachine.setOperationalMode(WifiStateMachine.DISABLED_MODE, null);

                if (mClientInterfaceName != null) {
                    mWifiNative.teardownInterface(mClientInterfaceName);
                    mClientInterfaceName = null;
                    mIfaceIsUp = false;
                }

                updateWifiState(WifiManager.WIFI_STATE_DISABLED,
                                WifiManager.WIFI_STATE_DISABLING);

                // once we leave started, nothing else to do...  stop the state machine
                mStateMachine.quitNow();
            }
        }

WifiNactive中后续则会调用到mWifiMonitor.stopMonitoring(),stopSupplicantIfNecessary(),stopHalAndWificondIfNecessary(),去停止监测,停止wpa_supplicant,停止hal服务等。

    /** Helper method invoked to teardown client iface and perform necessary cleanup */
    private void onClientInterfaceDestroyed(@NonNull Iface iface) {
        synchronized (mLock) {
            mWifiMonitor.stopMonitoring(iface.name);
            if (!unregisterNetworkObserver(iface.networkObserver)) {
                Log.e(TAG, "Failed to unregister network observer on " + iface);
            }
            if (!mSupplicantStaIfaceHal.teardownIface(iface.name)) {
                Log.e(TAG, "Failed to teardown iface in supplicant on " + iface);
            }
            if (!mWificondControl.tearDownClientInterface(iface.name)) {
                Log.e(TAG, "Failed to teardown iface in wificond on " + iface);
            }
            stopSupplicantIfNecessary();
            stopHalAndWificondIfNecessary();
        }
    }

Android 的WiFi打开关闭流程大致如此,不足之处后续会继续完善。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Android 11的WiFi打开函数调用流程图如下: 1. 点击设备的“设置”按钮,进入系统设置界面。 2. 在设置界面中找到“网络和互联网”的选项,点击进入。 3. 在网络和互联网界面中,找到并点击“WiFi”选项。 4. 进入WiFi设置界面后,点击“开启WiFi”按钮。 5. 设备调用系统的WiFi管理模块,开始执行WiFi打开流程。 6. WiFi管理模块首先检查设备的WiFi芯片状态,如果芯片已经关闭,则需要先打开WiFi芯片。 7. 如果WiFi芯片已经打开,则WiFi管理模块开始搜索可用的WiFi网络。 8. 当找到可用的WiFi网络时,WiFi管理模块会尝试连接到该网络。 9. 连接到WiFi网络后,设备会获取该网络的IP地址和其他网络相关信息。 10. 设备将WiFi连接状态设置为已连接,并通知系统和应用程序。 11. 如果WiFi连接失败或者没有可用的WiFi网络,WiFi管理模块将会关闭WiFi芯片并返回WiFi打开失败的信息。 以上就是Android 11的WiFi打开函数调用流程图。在实际执行中,可能还会有一些其他细节和错误处理逻辑,但总体而言,这个流程可以帮助用户打开设备的WiFi功能并连接到可用的WiFi网络。 ### 回答2: Android 11中的WiFi打开函数调用流程图如下: 1. 首先,应用程序通过调用WiFiManager类的getSystemService()方法获取系统的WiFi服务实例。 2. 接下来,应用程序通过调用WiFiManager类的setWifiEnabled()方法来打开WiFi功能。 3. WiFiManager类会将该请求传递给系统服务,即WifiService类。 4. WifiService类会通过调用WifiController类的方法来处理WiFi打开请求。 5. WifiController类会检查当前设备的权限和状态,以确定是否允许打开WiFi。 6. 如果设备具有足够的权限并且当前设备处于正确状态,则WifiController类会继续处理打开WiFi请求。 7. WifiController类会与驱动程序进行通信,以控制硬件设备的操作,从而打开WiFi。 8. 一旦WiFi硬件设备成功打开WifiController类会通知WifiService类。 9. WifiService类随后会通知应用程序,指示WiFi已成功打开。 10. 最后,应用程序可以进一步使用WiFi功能,如连接到可用的WiFi网络。 请注意,Android 11中的WiFi打开函数调用流程可能会因设备和系统定制而有所不同。上述流程图仅为概述,具体实现可能会有所差异。 ### 回答3: Android 11中的Wi-Fi打开函数调用流程图如下: 1. 应用程序调用Wi-Fi Manager类的`setWifiEnabled(true)`方法,用于打开Wi-Fi功能。 2. Wi-Fi Manager类将此请求发送给系统服务。 3. 系统服务接收到请求后,检查当前设备是否具有足够的权限来打开Wi-Fi。如果权限不足,服务将拒绝请求,并向应用程序返回相应的错误代码。 4. 如果应用程序具有足够的权限,系统服务将检查与Wi-Fi硬件驱动程序的通信是否正常。如果存在通信问题,服务将返回相应的错误代码。 5. 如果无任何问题,系统服务将向Wi-Fi硬件驱动程序发送打开Wi-Fi的指令。 6. Wi-Fi硬件驱动程序接收到指令后,控制Wi-Fi芯片打开相应的电路和无线射频器。 7. 一旦Wi-Fi硬件处于打开状态,驱动程序将返回成功的消息给系统服务。 8. 系统服务收到成功消息后,将其传递给Wi-Fi Manager类。 9. Wi-Fi Manager类会更新其内部状态,表示Wi-Fi已成功打开。 10. Wi-Fi Manager类将成功的消息返回给应用程序,通知其Wi-Fi已成功打开。 11. 应用程序可以通过检查Wi-Fi Manager类的状态来确认Wi-Fi是否已打开。 总的来说,Android 11中的Wi-Fi打开函数调用流程主要涉及应用程序调用Wi-Fi Manager类的方法,将请求传递给系统服务,然后由系统服务与Wi-Fi硬件驱动程序进行通信以打开Wi-Fi。最后,成功的消息将传递回应用程序,并更新Wi-Fi Manager类的内部状态。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值