国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

[Android][WIFI]手機作AP,關(guān)閉移動網(wǎng)絡(luò)后,STA端斷開重連問題分析

這篇具有很好參考價值的文章主要介紹了[Android][WIFI]手機作AP,關(guān)閉移動網(wǎng)絡(luò)后,STA端斷開重連問題分析。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

[Android][WIFI]手機作AP,關(guān)閉移動網(wǎng)絡(luò)后,STA端斷開重連問題分析

背景描述

測試平臺

Android版本:Android P(9.0)

復(fù)現(xiàn)步驟

  • 準(zhǔn)備兩臺移動設(shè)備,一臺作為AP,一臺作為STA;
  • 作為AP的設(shè)備具備移動網(wǎng)絡(luò)上網(wǎng),熱點網(wǎng)絡(luò)分享能力;
  • 打開作為AP的設(shè)備的移動網(wǎng)絡(luò)流量開關(guān),再打開熱點;
  • 作為STA的設(shè)備接入該AP,并等待其通路判斷完成,確保Internet網(wǎng)絡(luò)訪問能力正常;
  • 關(guān)閉作為AP的設(shè)備的移動網(wǎng)絡(luò)流量開關(guān);
  • 觀察

期望結(jié)果

STA端網(wǎng)絡(luò)保持連接,狀態(tài)變更為無Internet訪問能力提示

實際結(jié)果

STA端斷開,并隨后自動重連成功,狀態(tài)變更為無Internet訪問能力提示

問題分析

WifiStateMachine

打開STA端WiFi Verbose log后,抓取日志,首先確認(rèn)斷開的原因:

01-04 10:01:38.920 24751 24837 D WifiStateMachine:  ConnectedState !CMD_IP_CONFIGURATION_LOST rt=2214117/2214117 0 0 failures: 0/9 7e:d2:c5:43:c8:03 bcn=0
01-04 10:01:38.920 24751 24837 D WifiStateMachine:  L2ConnectedState !CMD_IP_CONFIGURATION_LOST rt=2214117/2214117 0 0 failures: 0/9 7e:d2:c5:43:c8:03 bcn=0
...
01-04 10:01:38.921 25250 25250 D wpa_supplicant: wlan0: Request to deauthenticate - bssid=7e:d2:c5:43:c8:03 pending_bssid=00:00:00:00:00:00 reason=3 (DEAUTH_LEAVING) state=COMPLETED

發(fā)現(xiàn)為主動斷開,而WifiStateMachine顯示狀態(tài)機在L2ConnectedState處理了CMD_IP_CONFIGURATION_LOST消息;
結(jié)合代碼來看,WifiStateMachineL2ConnectedState中處理CMD_IP_CONFIGURATION_LOST消息的邏輯中包含handleIpConfigurationLost()方法,后者會調(diào)用WifiNative.disconnect()發(fā)起斷開請求:

//frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java
    private void handleIpConfigurationLost() {
        mWifiInfo.setInetAddress(null);
        mWifiInfo.setMeteredHint(false);

        mWifiConfigManager.updateNetworkSelectionStatus(mLastNetworkId,
                WifiConfiguration.NetworkSelectionStatus.DISABLED_DHCP_FAILURE);

        /* DHCP times out after about 30 seconds, we do a
         * disconnect thru supplicant, we will let autojoin retry connecting to the network
         */
        mWifiNative.disconnect(mInterfaceName);
    }

    ...
    
	class L2ConnectedState extends State {
		...
        @Override
        public boolean processMessage(Message message) {
			...
            switch (message.what) {
				...
                case CMD_IP_CONFIGURATION_LOST:
                    // Get Link layer stats so that we get fresh tx packet counters.
                    getWifiLinkLayerStats();
                    handleIpConfigurationLost();
                    reportConnectionAttemptEnd(
                            WifiMetrics.ConnectionEvent.FAILURE_DHCP,
                            WifiMetricsProto.ConnectionEvent.HLF_NONE);
                    transitionTo(mDisconnectingState);
                    break;
				...
            }

            return HANDLED;
        }
    }

而發(fā)送發(fā)送CMD_IP_CONFIGURATION_LOST消息是由構(gòu)造IpClient時傳遞的IpClientCallback實例對象回調(diào)過來的:

//frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java
    private IpClient mIpClient;
    ...
    private FrameworkFacade mFacade;
    ...
	class IpClientCallback extends IpClient.Callback {
		...
        @Override
        public void onProvisioningFailure(LinkProperties newLp) {
            mWifiMetrics.logStaEvent(StaEvent.TYPE_CMD_IP_CONFIGURATION_LOST);
            sendMessage(CMD_IP_CONFIGURATION_LOST);
        }
        ...
    }
    ...
	private void setupClientMode() {
		...
        mIpClient = mFacade.makeIpClient(mContext, mInterfaceName, new IpClientCallback());
        mIpClient.setMulticastFilter(true);
        ...
    }

到這里,基本可以確定,是IpClient側(cè)的邏輯,觸發(fā)了WifiStateMachine.IpClientCallbackonProvisioningFailure()回調(diào)方法,導(dǎo)致STA端WLAN斷開;

接下來跳轉(zhuǎn)到IpClient繼續(xù)分析:

IpClient

IpClient側(cè)通常日志較少,需要添加日志:

public class IpClient extends StateMachine {
    private static final boolean DBG = true;
    ...
    private void configureAndStartStateMachine() {
		...
        setInitialState(mStoppedState);
        setDbg("wlan0".equals(mInterfaceName));
		...
    }
    ...
}

復(fù)現(xiàn)后可知:

01-04 10:01:38.918 24751 25461 D IpClient.wlan0: handleMessage: E msg.what=6
...
01-04 10:01:38.918 24751 25461 D IpClient.wlan0: processMsg: RunningState
01-04 10:01:38.919 24751 25461 D IpClient.wlan0: Netlink-seen LPs: {InterfaceName: wlan0 LinkAddresses: [fe80::ce88:26ff:fefb:a765/64,192.168.98.129/24,240e:476:bbc2:3fcf:ce88:26ff:fefb:a765/64,240e:476:bbc2:3fcf:40ae:51e9:8141:84b7/64,]  Routes: [fe80::/64 -> :: wlan0,] DnsAddresses: [240e:476:bbc2:3fcf::e6,] UsePrivateDns: false PrivateDnsServerName: null Domains: null MTU: 0}, new LPs: {InterfaceName: wlan0 LinkAddresses: [fe80::ce88:26ff:fefb:a765/64,192.168.98.129/24,240e:476:bbc2:3fcf:ce88:26ff:fefb:a765/64,240e:476:bbc2:3fcf:40ae:51e9:8141:84b7/64,]  Routes: [fe80::/64 -> :: wlan0,192.168.98.0/24 -> 0.0.0.0 wlan0,0.0.0.0/0 -> 192.168.98.27 wlan0,] DnsAddresses: [192.168.98.27,] UsePrivateDns: false PrivateDnsServerName: null Domains: null MTU: 0 TcpBufferSizes: 524288,1048576,2097152,262144,524288,1048576}; old LPs: {InterfaceName: wlan0 LinkAddresses: [fe80::ce88:26ff:fefb:a765/64,192.168.98.129/24,240e:476:bbc2:3fcf:ce88:26ff:fefb:a765/64,240e:476:bbc2:3fcf:40ae:51e9:8141:84b7/64,]  Routes: [fe80::/64 -> :: wlan0,::/0 -> fe80::7cd2:c5ff:fe43:c803 wlan0,240e:476:bbc2:3fcf::/64 -> :: wlan0,192.168.98.0/24 -> 0.0.0.0 wlan0,0.0.0.0/0 -> 192.168.98.27 wlan0,] DnsAddresses: [240e:476:bbc2:3fcf::e6,192.168.98.27,] UsePrivateDns: false PrivateDnsServerName: null Domains: null MTU: 0 TcpBufferSizes: 524288,1048576,2097152,262144,524288,1048576}
01-04 10:01:38.920 24751 25461 D IpClient.wlan0: onProvisioningFailure()

第一句日志輸出是在assembleLinkProperties()方法中:

//frameworks/base/services/net/java/android/net/ip/IpClient.java
	private LinkProperties assembleLinkProperties() {
        // [1] Create a new LinkProperties object to populate.
        LinkProperties newLp = new LinkProperties();
        newLp.setInterfaceName(mInterfaceName);

        // [2] Pull in data from netlink:
        //         - IPv4 addresses
        //         - IPv6 addresses
        //         - IPv6 routes
        //         - IPv6 DNS servers
        //
        // N.B.: this is fundamentally race-prone and should be fixed by
        // changing NetlinkTracker from a hybrid edge/level model to an
        // edge-only model, or by giving IpClient its own netlink socket(s)
        // so as to track all required information directly.
        LinkProperties netlinkLinkProperties = mNetlinkTracker.getLinkProperties();
        newLp.setLinkAddresses(netlinkLinkProperties.getLinkAddresses());
        for (RouteInfo route : netlinkLinkProperties.getRoutes()) {
            newLp.addRoute(route);
        }
        addAllReachableDnsServers(newLp, netlinkLinkProperties.getDnsServers());

        // [3] Add in data from DHCPv4, if available.
        //
        // mDhcpResults is never shared with any other owner so we don't have
        // to worry about concurrent modification.
        if (mDhcpResults != null) {
            for (RouteInfo route : mDhcpResults.getRoutes(mInterfaceName)) {
                newLp.addRoute(route);
            }
            addAllReachableDnsServers(newLp, mDhcpResults.dnsServers);
            newLp.setDomains(mDhcpResults.domains);

            if (mDhcpResults.mtu != 0) {
                newLp.setMtu(mDhcpResults.mtu);
            }
        }

        // [4] Add in TCP buffer sizes and HTTP Proxy config, if available.
        if (!TextUtils.isEmpty(mTcpBufferSizes)) {
            newLp.setTcpBufferSizes(mTcpBufferSizes);
        }
        if (mHttpProxy != null) {
            newLp.setHttpProxy(mHttpProxy);
        }

        // [5] Add data from InitialConfiguration
        if (mConfiguration != null && mConfiguration.mInitialConfig != null) {
            InitialConfiguration config = mConfiguration.mInitialConfig;
            // Add InitialConfiguration routes and dns server addresses once all addresses
            // specified in the InitialConfiguration have been observed with Netlink.
            if (config.isProvisionedBy(newLp.getLinkAddresses(), null)) {
                for (IpPrefix prefix : config.directlyConnectedRoutes) {
                    newLp.addRoute(new RouteInfo(prefix, null, mInterfaceName));
                }
            }
            addAllReachableDnsServers(newLp, config.dnsServers);
        }
        final LinkProperties oldLp = mLinkProperties;
        if (DBG) {
            Log.d(mTag, String.format("Netlink-seen LPs: %s, new LPs: %s; old LPs: %s",
                    netlinkLinkProperties, newLp, oldLp));
        }

        // TODO: also learn via netlink routes specified by an InitialConfiguration and specified
        // from a static IP v4 config instead of manually patching them in in steps [3] and [5].
        return newLp;
    }

結(jié)合狀態(tài)機的日志,可知是RunningState處理EVENT_NETLINK_LINKPROPERTIES_CHANGED消息時調(diào)用的assembleLinkProperties()方法:

//frameworks/base/services/net/java/android/net/ip/IpClient.java
	...
	class RunningState extends State {
        private ConnectivityPacketTracker mPacketTracker;
        private boolean mDhcpActionInFlight;
        ...
        @Override
        public boolean processMessage(Message msg) {
            switch (msg.what) {
				...
                case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
                    if (!handleLinkPropertiesUpdate(SEND_CALLBACKS)) {
                        transitionTo(mStoppingState);
                    }
                    break;
				...
            }
			...
        }
    }

結(jié)合代碼分析,可知這部分邏輯應(yīng)該是這樣的:

  1. AP端關(guān)閉移動網(wǎng)絡(luò)流量開關(guān)后,STA端IPV6地址與路由表發(fā)生改變;
  2. NetlinkTrackerNetd接收到這些改變的事件,并通過NetlinkTracker.Callback.update()回調(diào)給到IpClient.mNetlinkTracker
  3. IpClient.mNetlinkTracker收到update()事件回調(diào)后,向IpClient狀態(tài)機發(fā)送EVENT_NETLINK_LINKPROPERTIES_CHANGED消息;
  4. IpClient如果此時處于RunningState,那么在處理EVENT_NETLINK_LINKPROPERTIES_CHANGED消息時,會觸發(fā)onProvisioningFailure()方法回調(diào);
  5. onProvisioningFailure()方法回調(diào)會通過構(gòu)造時注冊進來的IpClient.Callback回調(diào)實例,通知到WifiStateMachine,后者會執(zhí)行斷開邏輯;

梳理完了整個流程,接下來就需要分析上面的第4步中最后一個疑點——onProvisioningFailure()為何會執(zhí)行;

前面已經(jīng)分析到了: IpClientRunningState下處理EVENT_NETLINK_LINKPROPERTIES_CHANGED消息會調(diào)用handleLinkPropertiesUpdate()方法,參數(shù)為SEND_CALLBACKS,恒為true

//frameworks/base/services/net/java/android/net/ip/IpClient.java
    private void dispatchCallback(ProvisioningChange delta, LinkProperties newLp) {
        switch (delta) {
			...
            case LOST_PROVISIONING:
                if (DBG) { Log.d(mTag, "onProvisioningFailure()"); }
                recordMetric(IpManagerEvent.PROVISIONING_FAIL);
                mCallback.onProvisioningFailure(newLp);
                break;
			...
        }
    }

    ...

    // Returns false if we have lost provisioning, true otherwise.
	private boolean handleLinkPropertiesUpdate(boolean sendCallbacks) {
        final LinkProperties newLp = assembleLinkProperties();
        if (Objects.equals(newLp, mLinkProperties)) {
            return true;
        }
        final ProvisioningChange delta = setLinkProperties(newLp);
        if (sendCallbacks) {
            dispatchCallback(delta, newLp);
        }
        return (delta != ProvisioningChange.LOST_PROVISIONING);
    }

handleLinkPropertiesUpdate()方法實現(xiàn)內(nèi)部,有一個名為delta的局部常量,類型為ProvisioningChange枚舉,當(dāng)delta這個局部常量賦值為setLinkProperties()方法的返回結(jié)果;

如果返回結(jié)果為LOST_PROVISIONING,則會通過dispatchCallback()方法觸發(fā)onProvisioningFailure()回調(diào),從而出現(xiàn)上面整個鏈路,導(dǎo)致STA斷連;

handleLinkPropertiesUpdate()方法內(nèi)部,最重要的兩個方法是:assembleLinkProperties()setLinkProperties(newLp);

依次來看:

//frameworks/base/services/net/java/android/net/ip/IpClient.java

	private LinkProperties assembleLinkProperties() {
        // [1] Create a new LinkProperties object to populate.
        LinkProperties newLp = new LinkProperties();
        newLp.setInterfaceName(mInterfaceName);

        // [2] Pull in data from netlink:
        //         - IPv4 addresses
        //         - IPv6 addresses
        //         - IPv6 routes
        //         - IPv6 DNS servers
        //
        // N.B.: this is fundamentally race-prone and should be fixed by
        // changing NetlinkTracker from a hybrid edge/level model to an
        // edge-only model, or by giving IpClient its own netlink socket(s)
        // so as to track all required information directly.
        LinkProperties netlinkLinkProperties = mNetlinkTracker.getLinkProperties();
        newLp.setLinkAddresses(netlinkLinkProperties.getLinkAddresses());
        for (RouteInfo route : netlinkLinkProperties.getRoutes()) {
            newLp.addRoute(route);
        }
        addAllReachableDnsServers(newLp, netlinkLinkProperties.getDnsServers());

        // [3] Add in data from DHCPv4, if available.
        //
        // mDhcpResults is never shared with any other owner so we don't have
        // to worry about concurrent modification.
        if (mDhcpResults != null) {
            for (RouteInfo route : mDhcpResults.getRoutes(mInterfaceName)) {
                newLp.addRoute(route);
            }
            addAllReachableDnsServers(newLp, mDhcpResults.dnsServers);
            newLp.setDomains(mDhcpResults.domains);

            if (mDhcpResults.mtu != 0) {
                newLp.setMtu(mDhcpResults.mtu);
            }
        }

        // [4] Add in TCP buffer sizes and HTTP Proxy config, if available.
        if (!TextUtils.isEmpty(mTcpBufferSizes)) {
            newLp.setTcpBufferSizes(mTcpBufferSizes);
        }
        if (mHttpProxy != null) {
            newLp.setHttpProxy(mHttpProxy);
        }

        // [5] Add data from InitialConfiguration
        if (mConfiguration != null && mConfiguration.mInitialConfig != null) {
            InitialConfiguration config = mConfiguration.mInitialConfig;
            // Add InitialConfiguration routes and dns server addresses once all addresses
            // specified in the InitialConfiguration have been observed with Netlink.
            if (config.isProvisionedBy(newLp.getLinkAddresses(), null)) {
                for (IpPrefix prefix : config.directlyConnectedRoutes) {
                    newLp.addRoute(new RouteInfo(prefix, null, mInterfaceName));
                }
            }
            addAllReachableDnsServers(newLp, config.dnsServers);
        }
        final LinkProperties oldLp = mLinkProperties;
        if (DBG) {
            Log.d(mTag, String.format("Netlink-seen LPs: %s, new LPs: %s; old LPs: %s",
                    netlinkLinkProperties, newLp, oldLp));
        }

        // TODO: also learn via netlink routes specified by an InitialConfiguration and specified
        // from a static IP v4 config instead of manually patching them in in steps [3] and [5].
        return newLp;
    }

assembleLinkProperties()這個方法主要完成了如下任務(wù):

  1. 通過 mNetlinkTracker.getLinkProperties()獲取當(dāng)前探測到的最新的鏈路信息,并封裝為LinkProperties返回,賦值給netlinkLinkProperties
  2. netlinkLinkProperties中的需要關(guān)注的信息(LinkAddresses、RouteInfo等)拷貝到newLp這個局部變量中;
  3. 返回newLp

handleLinkPropertiesUpdate()方法內(nèi)在收到assembleLinkProperties()方法的返回值后,會判斷與當(dāng)前的成員變量mLinkProperties是否相同;

LinkProperties重寫了equals方法:

//frameworks/base/core/java/android/net/LinkProperties.java
	...
    @Override
    /**
     * Compares this {@code LinkProperties} instance against the target
     * LinkProperties in {@code obj}. Two LinkPropertieses are equal if
     * all their fields are equal in values.
     *
     * For collection fields, such as mDnses, containsAll() is used to check
     * if two collections contains the same elements, independent of order.
     * There are two thoughts regarding containsAll()
     * 1. Duplicated elements. eg, (A, B, B) and (A, A, B) are equal.
     * 2. Worst case performance is O(n^2).
     *
     * @param obj the object to be tested for equality.
     * @return {@code true} if both objects are equal, {@code false} otherwise.
     */
    public boolean equals(Object obj) {
        if (this == obj) return true;

        if (!(obj instanceof LinkProperties)) return false;

        LinkProperties target = (LinkProperties) obj;
        /**
         * This method does not check that stacked interfaces are equal, because
         * stacked interfaces are not so much a property of the link as a
         * description of connections between links.
         */
        return isIdenticalInterfaceName(target)
                && isIdenticalAddresses(target)
                && isIdenticalDnses(target)
                && isIdenticalPrivateDns(target)
                && isIdenticalValidatedPrivateDnses(target)
                && isIdenticalRoutes(target)
                && isIdenticalHttpProxy(target)
                && isIdenticalStackedLinks(target)
                && isIdenticalMtu(target)
                && isIdenticalTcpBufferSizes(target);
    }
    ...

由此可見,滿足equals的要求非??量?,只要有任何變動,都會導(dǎo)致返回值為false;

回到此問題,由于IPV6的相關(guān)地址變更,其關(guān)聯(lián)的路由規(guī)則與地址信息均會發(fā)生改變,因此這里必然會返回false

由此,我們來看第二個重要的方法——setLinkProperties()

//frameworks/base/services/net/java/android/net/ip/IpClient.java
	...
    static boolean isProvisioned(LinkProperties lp, InitialConfiguration config) {
        // For historical reasons, we should connect even if all we have is
        // an IPv4 address and nothing else.
        if (lp.hasIPv4Address() || lp.isProvisioned()) {
            return true;
        }
        if (config == null) {
            return false;
        }

        // When an InitialConfiguration is specified, ignore any difference with previous
        // properties and instead check if properties observed match the desired properties.
        return config.isProvisionedBy(lp.getLinkAddresses(), lp.getRoutes());
    }

	...

    private ProvisioningChange compareProvisioning(LinkProperties oldLp, LinkProperties newLp) {
        ProvisioningChange delta;
        InitialConfiguration config = mConfiguration != null ? mConfiguration.mInitialConfig : null;
        final boolean wasProvisioned = isProvisioned(oldLp, config);
        final boolean isProvisioned = isProvisioned(newLp, config);

        if (!wasProvisioned && isProvisioned) {
            delta = ProvisioningChange.GAINED_PROVISIONING;
        } else if (wasProvisioned && isProvisioned) {
            delta = ProvisioningChange.STILL_PROVISIONED;
        } else if (!wasProvisioned && !isProvisioned) {
            delta = ProvisioningChange.STILL_NOT_PROVISIONED;
        } else {
			...
            delta = ProvisioningChange.LOST_PROVISIONING;
        }

        final boolean lostIPv6 = oldLp.isIPv6Provisioned() && !newLp.isIPv6Provisioned();
        final boolean lostIPv4Address = oldLp.hasIPv4Address() && !newLp.hasIPv4Address();
        final boolean lostIPv6Router = oldLp.hasIPv6DefaultRoute() && !newLp.hasIPv6DefaultRoute();
		...
        final boolean ignoreIPv6ProvisioningLoss = (mMultinetworkPolicyTracker != null)
                && !mMultinetworkPolicyTracker.getAvoidBadWifi();

		...
        if (lostIPv4Address || (lostIPv6 && !ignoreIPv6ProvisioningLoss)) {
            delta = ProvisioningChange.LOST_PROVISIONING;
        }
		...
        if (oldLp.hasGlobalIPv6Address() && (lostIPv6Router && !ignoreIPv6ProvisioningLoss)) {
            delta = ProvisioningChange.LOST_PROVISIONING;
        }

        return delta;
    }

    // Updates all IpClient-related state concerned with LinkProperties.
    // Returns a ProvisioningChange for possibly notifying other interested
    // parties that are not fronted by IpClient.
    private ProvisioningChange setLinkProperties(LinkProperties newLp) {
		...
        ProvisioningChange delta = compareProvisioning(mLinkProperties, newLp);
        mLinkProperties = new LinkProperties(newLp);
		...
        return delta;
    }

	...

    // Returns false if we have lost provisioning, true otherwise.
    private boolean handleLinkPropertiesUpdate(boolean sendCallbacks) {
		...
        final ProvisioningChange delta = setLinkProperties(newLp);
        if (sendCallbacks) {
            dispatchCallback(delta, newLp);
        }
        return (delta != ProvisioningChange.LOST_PROVISIONING);
    }

這里方法跳轉(zhuǎn)比較多,概括一下:

  1. setLinkProperties由于需要一個ProvisioningChange枚舉的返回結(jié)果,因此不僅僅是將參數(shù)生拷貝到成員變量mLinkProperties,在此之前需要調(diào)用compareProvisioning方法對mLinkProperties與傳入?yún)?shù)newLp進行對比,并將差異返回,賦值給局部常量delta,后者也是整個setLinkProperties方法的返回結(jié)果;
  2. compareProvisioning方法主要通過對比兩個傳入?yún)?shù)的isProvisioned方法返回結(jié)果,來判定這次變動是GAINED_PROVISIONINGSTILL_PROVISIONED,STILL_NOT_PROVISIONED,還是LOST_PROVISIONING;
  3. 此外,如果compareProvisioning方法內(nèi)的局部變量ignoreIPv6ProvisioningLoss不為true,IPV6地址、網(wǎng)關(guān)、DNS的丟失也會導(dǎo)致返回結(jié)果為LOST_PROVISIONING

而此問題出現(xiàn),就是滿足了第3條條件所致;

解決方案

由上可知,此行為是AOSP原生邏輯,旨在使STA自動規(guī)避無法上網(wǎng)的AP;

因此:文章來源地址http://www.zghlxwxcb.cn/news/detail-495316.html

  1. 此問題若非強需求,可以不處理;
  2. 若需要屏蔽掉此行為,只需將config_networkAvoidBadWifi修改為0即可;

到了這里,關(guān)于[Android][WIFI]手機作AP,關(guān)閉移動網(wǎng)絡(luò)后,STA端斷開重連問題分析的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Android 12 Wifi 開發(fā)(獲取列表、連接、斷開連接)

    獲取Wifi列表: 掃描(這個方法早在Android 9.0 就被棄用), 不過如果不調(diào)用的話是沒法及時獲取Wifi列表的廣播的。 (不需要也能正常獲取,沒有延遲,經(jīng)實驗毫無區(qū)別) 創(chuàng)建廣播并接收: 配置并連接( 無系統(tǒng)簽名 ): 配置并連接( 有系統(tǒng)簽名 ): 斷開連接(無系統(tǒng)簽名

    2024年02月03日
    瀏覽(24)
  • Google系列Android手機無法聯(lián)網(wǎng)/無法上網(wǎng)/WIFI網(wǎng)絡(luò)受限等問題的解決方法

    https://m.weishi100.com/mweb/single/1666650236443/?id=8960958 https://m.weishi100.com/mweb/series/?id=1372437 https://m.weishi100.com/mweb/series/?id=1373351

    2024年02月04日
    瀏覽(23)
  • RabbitMQ連接斷開自動重連問題解決

    RabbitMQ是一個功能強大的消息代理,被廣泛用于構(gòu)建分布式應(yīng)用程序。然而,有時候在使用RabbitMQ時會遇到連接斷開的問題,這可能會導(dǎo)致消息傳遞中斷和應(yīng)用程序的不可用性。在本文中,我們將探討如何解決RabbitMQ連接斷開的問題,并提供相應(yīng)的源代碼示例。 當(dāng)使用RabbitMQ時

    2024年02月05日
    瀏覽(40)
  • RK3288 Android5.1添加WiFi&BT模塊AP6212

    RK3288 Android5.1添加WiFi&BT模塊AP6212

    CPU:RK3288 系統(tǒng):Android 5.1 注:RK3288系統(tǒng),目前 Android 5.0 Kernel 3.10 SDK 支持 Braodcom,Realtek 等 WiFi BT 模塊 各個 WiFi BT 模塊已經(jīng)做到動態(tài)兼容,Android 上層不再需要像以前一樣進 行特定宏的配置 此文是手動添加AP6212A的例程。 1、在設(shè)備樹中修改 wifi 芯片為 ap6212a(找到自己對應(yīng)的

    2024年02月07日
    瀏覽(25)
  • nginx代理socket鏈接集群后,頻繁斷開重連

    nginx代理socket鏈接集群后,頻繁斷開重連

    nginx使用集群模式代理多個socket鏈接,socket鏈接頻繁斷開重連 1、nginx錯誤日志 2、nginx訪問日志 從日志上可以看到,斷開重連頻率非常高,每隔幾十毫秒就會鏈接一次 是nginx集群的負(fù)載均衡策略有問題,因為沒有在 test_socket集群 指定策略,所以nginx默認(rèn)使用的是 輪詢策略 那為

    2024年02月09日
    瀏覽(19)
  • 實際案例記錄:華三AP,wa6638i,能獲取管理地址,手機連接不上wifi,一直顯示獲取ip中

    基本配置:wa6638i,硬件端口:1、電口10G+POE,2、電口10G+POE,3、光口SFP-10G,4、串口,5、POE OUT輸出物聯(lián)模塊端口 ? 使用問題:AP在AC控制器上線,并獲取到管理vlan地址。電腦連接上wifi,可是網(wǎng)絡(luò)適配器顯示沒有獲取到業(yè)務(wù)vlan地址。手機連接wifi顯示IP地址獲取中一直連接不上

    2024年02月10日
    瀏覽(21)
  • 手機移動數(shù)據(jù)關(guān)閉了 會影響什么

    今天將android手機關(guān)閉了移動數(shù)據(jù),又怕影響別的wifi上網(wǎng)之類的,其實關(guān)閉了就不會才產(chǎn)生流量使用和費用,wifi可以正常使用。 你關(guān)閉了,天氣等軟件就不能再更新了手機移動數(shù)據(jù),這樣既省電還省錢了,不過如果用微信,qq的時候需要開啟的,所以我們一般晚上睡覺的時候關(guān)

    2024年02月05日
    瀏覽(20)
  • ESP8266WiFi模塊與Android APP實現(xiàn)數(shù)據(jù)傳輸(二)---AP模式通訊

    ESP8266WiFi模塊與Android APP實現(xiàn)數(shù)據(jù)傳輸(二)---AP模式通訊

    前言: 1.ESP8266模塊設(shè)定: (1)準(zhǔn)備階段: (2)AT指令配置WiFi模塊: 2.Android手機端APP設(shè)置: 3.ESP8266與APP通訊: ?4.串口調(diào)試器和APP程序等資源下載途徑 ????????本文主要介紹一下ESP8266WiFi模塊與Andriod APP實現(xiàn)數(shù)據(jù)傳輸?shù)?AP模式 通訊。 ESP8266模塊 三種模式 : ????????1、STA模式

    2024年02月01日
    瀏覽(23)
  • 利用Api接口實現(xiàn)手機網(wǎng)絡(luò)連接斷開的監(jiān)聽

    利用Api接口實現(xiàn)手機網(wǎng)絡(luò)連接斷開的監(jiān)聽

    在今天的移動互聯(lián)網(wǎng)時代,手機已經(jīng)成為了人們不可或缺的重要工具,而手機的聯(lián)網(wǎng)狀態(tài)也是我們經(jīng)常需要關(guān)注的一個問題。我們需要保證手機網(wǎng)絡(luò)處于正常的連接狀態(tài),但是有時候,由于種種原因,手機的網(wǎng)絡(luò)可能會斷開,這時我們需要及時發(fā)現(xiàn),并進行相應(yīng)的處理措施。

    2024年02月09日
    瀏覽(20)
  • 一加8手機【ColorOS Android 13】使用Android Studio在Debug斷點調(diào)試時自動斷開崩潰

    一加8手機【ColorOS Android 13】使用Android Studio在Debug斷點調(diào)試時自動斷開崩潰

    一加8手機(系統(tǒng)是ColorOS? Android版本: 13) 在使用android studio進行usb調(diào)試過程中, 總是在幾秒鐘之后就自動崩潰退出應(yīng)用(代碼正常,使用其他測試機正常調(diào)試), 調(diào)試自然也就斷開了; ?解決辦法: 將【禁止權(quán)限監(jiān)控】開關(guān) 打開即可; --【其他設(shè)置】--【開發(fā)者選項】--【應(yīng)用】--【禁止

    2024年02月12日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包