Android 系统连接WIFI显示网络连担当限分析处理

火影  论坛元老 | 2024-10-26 00:42:07 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1021|帖子 1021|积分 3063

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
Android 系统连接WIFI显示网络连担当限分析处理


  
一、媒介

Android 系统连接WIFI提示网络受限处理这个是比较常见的问题了,这里简单纪录一下。
Android原生系统连接国内wifi网络会提示不可用,
之后显示网络受限,但是实际可以上网;
连接国外VPN网络是没有这个问题的。
这个问题的原因就是系统连接上wifi后校验网络的时间,
使用的是一个国外的url地址,但是国内外访问这个地址是无法返回数据的,
所以系统才会判定该wifi无法连接网络。
要解决这个问题,有两种方法:
一个是替换了校验网络的url地址,别的一个是去除这个校验过程。
这个问题许多文章都有先容,这里是基于Android14举行了简单分析,又想去的可以看看。
二、分析处理

1、NetworkMonitor 网络监视器

连接国内外wifi打印的日记:
  1. console:/ # logcat | grep NetworkMonitor
  2. NetworkMonitor/100: checkAndRenewResourceConfig: update captive portal https urls to [https://www.google.com/generate_204]
  3. NetworkMonitor/100: checkAndRenewResourceConfig: update captive portal http urls to [http://connectivitycheck.gstatic.com/generate_204]
  4. NetworkMonitor/100: checkAndRenewResourceConfig: update captive portal fallback urls to[http://www.google.com/gen_204, http://play.googleapis.com/generate_204]
  5. NetworkMonitor: Starting on network 100 with capport HTTPS URL [https://www.google.com/generate_204] and HTTP URL [http://connectivitycheck.gstatic.com/generate_204]
  6. NetworkMonitor/100: PROBE_DNS www.google.com 43ms OK 31.13.73.169
  7. NetworkMonitor/100: PROBE_DNS connectivitycheck.gstatic.com 61ms OK 203.208.40.34
  8. UpstreamNetworkMonitor: New default Internet network: 100
  9. NetworkMonitor/100: PROBE_HTTP http://connectivitycheck.gstatic.com/generate_204 time=234ms ret=204 request={Connection=[close], User-Agent=[Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.32 Safari/537.36]} headers={null=[HTTP/1.1 204 No Content], Connection=[close], Content-Length=[0], Cross-Origin-Resource-Policy=[cross-origin], Date=[Sun, 25 Aug 2024 09:25:50 GMT], X-Android-Received-Millis=[1724577945932], X-Android-Response-Source=[NETWORK 204], X-Android-Selected-Protocol=[http/1.1], X-Android-Sent-Millis=[1724577945815]}
  10. NetworkMonitor/100: PROBE_HTTPS https://www.google.com/generate_204 Probe failed with exception java.net.SocketTimeoutException: failed to connect to www.google.com/31.13.73.169 (port 443) from /192.168.31.38 (port 51034) after 10000ms
  11. NetworkMonitor/100: PROBE_FALLBACK http://www.google.com/gen_204 Probe failed with exception java.net.SocketTimeoutException: failed to connect to www.google.com/31.13.73.169 (port 80) from /192.168.31.38 (port 49544) after 10000ms
  12. NetworkMonitor/100: isCaptivePortal: isSuccessful()=false isPortal()=false RedirectUrl=null isPartialConnectivity()=false Time=13014ms
复制代码
这里可以看到访问的国外网的url并且访问是返回失败的。
2、源码分析

package\modules\NetworkStack\src\com\android\server\connectivity\NetworkMonitor.java
  1. public class NetworkMonitor extends StateMachine {
  2.     private static final String TAG = NetworkMonitor.class.getSimpleName();
  3.     private static final boolean DBG  = true;
  4.     private static final boolean VDBG = false;
  5.     @NonNull
  6.     private URL[] mCaptivePortalFallbackUrls; //重定向网址
  7.     @NonNull
  8.     private URL[] mCaptivePortalHttpUrls;//http校验网址
  9.     @NonNull
  10.     private URL[] mCaptivePortalHttpsUrls; //https校验网址
  11.     //http 校验的默认网址
  12.     public String getCaptivePortalServerHttpUrl(@NonNull Context context) {
  13.         return getSettingFromResource(context,
  14.                 R.string.config_captive_portal_http_url, mCaptivePortalHttpUrlFromSetting,
  15.                 context.getResources().getString(
  16.                 R.string.default_captive_portal_http_url));
  17.     }
  18.     //https 校验的默认网址
  19.     private String getCaptivePortalServerHttpsUrl(@NonNull Context context) {
  20.         return getSettingFromResource(context,
  21.                 R.string.config_captive_portal_https_url, mCaptivePortalHttpsUrlFromSetting,
  22.                 context.getResources().getString(
  23.                 R.string.default_captive_portal_https_url));
  24.     }
  25.     //https 校验网址的数组合成
  26.     private URL[] makeCaptivePortalHttpsUrls(@NonNull Context context) {
  27.         final URL testUrl = getTestUrl(TEST_CAPTIVE_PORTAL_HTTPS_URL);
  28.         if (testUrl != null) return new URL[] { testUrl };
  29.         final String firstUrl = getCaptivePortalServerHttpsUrl(context); //获取默认的https校验网址
  30.         try {
  31.             final URL[] settingProviderUrls =
  32.                 combineCaptivePortalUrls(firstUrl, CAPTIVE_PORTAL_OTHER_HTTPS_URLS);
  33.             // firstUrl will at least be default configuration, so default value in
  34.             // getProbeUrlArrayConfig is actually never used.
  35.             return getProbeUrlArrayConfig(context, settingProviderUrls,
  36.                     R.array.config_captive_portal_https_urls,
  37.                     DEFAULT_CAPTIVE_PORTAL_HTTPS_URLS, this::makeURL);
  38.         } catch (Exception e) {
  39.             // Don't let a misconfiguration bootloop the system.
  40.             Log.e(TAG, "Error parsing configured https URLs", e);
  41.             // Ensure URL aligned with legacy configuration.
  42.             return new URL[]{makeURL(firstUrl)};
  43.         }
  44.     }
  45. }
复制代码
这里可以看到url网址的校验和获取的是哪个config名称的URL网址。
值得注意的是Android13 之后,url网址可以添加多个了,
Android13 之前的代码都是没有添加多个的,都是当个的http大概https。
实在这个问题我之前也是感觉只校验一个网址的情况确认不保险,
这个应该是Google 也发现了这个问题后举行了优化处理,可以对多个url举行校验后再判定网络是否可用。
NTP网址校验也有这个问题。这个没有举行后续优化,但是这个自己是有多个优先级获取的。
3、定义默认校验的网址

package\modules\NetworkStack\res\values\config.xml
  1.     <string name="default_captive_portal_http_url" translatable="false">http://connectivitycheck.gstatic.com/generate_204</string> //http
  2.     <string name="default_captive_portal_https_url" translatable="false">https://www.google.com/generate_204</string> //https
  3.     <string-array name="default_captive_portal_fallback_urls" translatable="false">
  4.         <item>http://www.google.com/gen_204</item>
  5.         <item>http://play.googleapis.com/generate_204</item>
  6.     </string-array>
复制代码
修改这个网址乐成国内外的就可以乐成校验到网络了。
但是万一国外网又不可以校验,那不是有bug?
所有要思量清楚是否会卖到国外的情况,才做修改;
要么找到兼容的网址,要么直接去除这个校验。
4、多个校验网址的设置

package\modules\NetworkStack\src\com\android\networkstack\util\NetworkStackUtils.java
  1.     public static final String[] DEFAULT_CAPTIVE_PORTAL_HTTP_URLS =
  2.             new String [] {"http://connectivitycheck.gstatic.com/generate_204"};
  3.     /**
  4.      * The default list of HTTPS URLs for network validation, to use for confirming internet
  5.      * connectivity.
  6.      */
  7.     public static final String[] DEFAULT_CAPTIVE_PORTAL_HTTPS_URLS =
  8.             new String [] {"https://www.google.com/generate_204"};
复制代码
上面是http和https校验的数组网址。
这里定义的两个数组在 NetworkMonitor 中确实也有引用到,但是不确定修改了是否有没有结果。
这个是直接写死在Java代码中的。
5、设置网络是否校验的代码

(1)Java 代码分析

package\modules\NetworkStack\src\com\android\server\connectivity\NetworkMonitor.java
  1.     private CaptivePortalProbeResult isCaptivePortal(ValidationProperties properties,
  2.             URL[] httpsUrls, URL[] httpUrls, URL fallbackUrl) {
  3.         if (!mIsCaptivePortalCheckEnabled) {
  4.             validationLog("Validation disabled.");
  5.             return CaptivePortalProbeResult.success(CaptivePortalProbeResult.PROBE_UNKNOWN);
  6.         }
  7.         。。。
  8.     }
  9.     private static boolean getIsCaptivePortalCheckEnabled(@NonNull Context context,
  10.             @NonNull Dependencies dependencies) {
  11.         String symbol = CAPTIVE_PORTAL_MODE; //其实就是这个Settings属性
  12.         int defaultValue = CAPTIVE_PORTAL_MODE_PROMPT; //默认校验
  13.         int mode = dependencies.getSetting(context, symbol, defaultValue);
  14.         return mode != CAPTIVE_PORTAL_MODE_IGNORE;
  15.     }
  16.         public int getSetting(Context context, String symbol, int defaultValue) {
  17.             return Settings.Global.getInt(context.getContentResolver(), symbol, defaultValue);
  18.         }
复制代码
具体判定过程可以在源码内里再梳理一下,但是实际起作用的就是一个Settings属性,
如果没有设置Settings属性,就是默认校验的情况。
(2)检测干系定义值

package\modules\NetworkStack\src\com\android\networkstack\util\NetworkStackUtils.java
  1.     public static final String CAPTIVE_PORTAL_MODE = "captive_portal_mode";
  2.     //0 不检测
  3.     public static final int CAPTIVE_PORTAL_MODE_IGNORE = 0;
  4.    //1默认弹框提示,默认
  5.     public static final int CAPTIVE_PORTAL_MODE_PROMPT = 1;
  6.     //2检测到需要登录则自动断开此热点并不再自动连接
  7.     public static final int CAPTIVE_PORTAL_MODE_AVOID = 2;
复制代码
(3)设置不举行网络校验的方法

有两种方法,
一个是设置一次网络校验的值,
还有就是在Settings属性加载的时间load这个属性值。
①Java应用中设置默认属性

  1.     private void setWifiNotCheckNetwork(Context context) {
  2.         ContentResolver cr = context.getContentResolver();
  3.         // 0 不检测,1默认弹框提示,2检测到需要登录则自动断开此热点并不再自动连接
  4.         Settings.Global.putInt(cr, Settings.Global.CAPTIVE_PORTAL_MODE, Settings.Global.CAPTIVE_PORTAL_MODE_IGNORE);
  5.     }
复制代码
在启动比较早的系统服务中设置就行,
设置一次大概每次启动都是都是没啥问题的。
② SettingsProvider 加载默认值

frameworks\base\packages\SettingsProvider\src\com\android\providers\settings\DatabaseHelper.java
  1.     loadBooleanSetting(stmt, Settings.Global.WIFI_ON,R.bool.def_wifi_on);
  2.     //参考wifi开关状态的方法,添加一行就行
  3.     loadBooleanSetting(stmt, Settings.Global.CAPTIVE_PORTAL_MODE, 0);
复制代码
实在这个网络校验好像没啥用,直接去掉就OK了;
还改啥默认校验的url多麻烦!
三、其他

1、Android 系统连接WIFI网络显示网络连担当限分析处理小结

处理方式要么修改默认url,要么去除url的校验过程。
去除url校验后,就是直接显示已连接,不行再显示网络受限等信息。
设置多个url校验的情况,不确定是否有用。必要自己尝试验证。
2、adb 验证测试系统连接WIFI网络显示网络连接校验

代码设置的Settings属性,也可以用adb 控制测试。
  1. C:\Users\As40>adb shell
  2. //获取当前校验状态
  3. rk3588_t:/ #
  4. rk3588_t:/ # settings get global captive_portal_mode
  5. null //未设置前获取null,默认是检测网络
  6. //设置不校验状态,重启是记忆的
  7. rk3588_t:/ # settings put global captive_portal_mode 0
  8. rk3588_t:/ #
  9. rk3588_t:/ # settings get global captive_portal_mode
  10. 0
  11. rk3588_t:/ #
复制代码
3、Android adb查看网络连接情况

  1. adb shell ifconfig //查看配置信息
  2. adb shell dumpsys connectivity  //查看连接情况
  3. db shell netstat //查看连接状态和地址
  4. adb shell ip ru //查看路由策略
复制代码
具体情况先容:
https://blog.csdn.net/wenzhi20102321/article/details/122161589
4、Android11 使用NTP同步时间

https://blog.csdn.net/wenzhi20102321/article/details/127482145

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

火影

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表