• Android11 实现有线网络和wifi共存


    Android11 实现有线网络和wifi共存

    一、前言

    Android 系统Framework进行一定适配后,可以实现wifi和有线网络端口都打开的,
    进而在App端即可实现通过代码控制选择使用wifi或者有线网络进行网络请求。

    本文只介绍wifi和有线网络端口同时打开的实现,app代码请求特定网络另外文章介绍。

    Android 默认是只保留打开一个网络的,其他网络是关闭的;
    手机一般是wifi或者Sim卡;
    一些的定制设备,比如商显大屏或者Android盒子,一般是wifi或者有线网络(以太网)。

    Android 系统6以后网络切换是以Score分值进行判断,分值越高越优先,
    比如wifi的分值为60,Sim卡的分值为50,所以wifi连接成功后,优先使用的是wifi网络。
    有线网的分值为70,比wifi优先。

    这个Score根据不同系统版本和设备情况,Score分值会有不同,但是都是根据分值确定确定优先级的。

    优先级的判断主要在 NetworkFactory.java和它的子类WifiNetworkFactory.java、EthernetNetworkFactory.java
    网络的切换逻辑判断主要在ConnectivityService.java类

    不同的系统版本位置不一样,需要在自己代码环境中查找
    find . -name “NetworkFactory.java”

    二、实现有线网络和wifi共存

    看了很多网上的方法,都不能生效,估计是Android11 代码结构有修改。

    方式1:修改 ConnectivityService.java

    对比了下Android9和Android11的 ConnectivityService.java ,发现变化很大,逻辑变得复制了很多。

    找了很多网上的方法说是把 teardownUnneededNetwork方法的nai.asyncChannel.disconnect()注释掉就可以了;
    frameworks\base\services\core\java\com\android\server\ConnectivityService.java

        private void teardownUnneededNetwork(NetworkAgentInfo nai) {
            if (nai.numRequestNetworkRequests() != 0) {
                for (int i = 0; i < nai.numNetworkRequests(); i++) {
                    NetworkRequest nr = nai.requestAt(i);
                    // Ignore listening requests.
                    if (nr.isListen()) continue;
                    loge("Dead network still had at least " + nr);
                    break;
                }
            }
            //nai.asyncChannel.disconnect();
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    但是我试了一下,在Android11 不行哎,
    搜索发现 ConnectivityService.java里面还有两个 nai.asyncChannel.disconnect(),把这两个都注释掉就可以了。

    研究过网络请求和释放,会知道网络的最终执行都是在NetworkFactory和相关子类;
    所以在NetworkFactory.java把网络释放注释掉是最保险的。
    因为在ConnectivityService到NetworkFactory直接还有很多相关的代理对象和过程。

    方式2:修改 NetworkFactory.java

    frameworks\libs\net\common\src_servicescommon\android\net\NetworkFactory.java

    
        private void evalRequest(NetworkRequestInfo n) {
            if (VDBG) {
                log("evalRequest");
                log(" n.requests = " + n.requested);
                log(" n.score = " + n.score);
                log(" mScore = " + mScore);
                log(" request.providerId = " + n.providerId);
                log(" mProvider.id = " + mProvider.getProviderId());
            }
            if (shouldNeedNetworkFor(n)) { //1、要确保执行到needNetworkFor方法一次,才能正常请求网络,shouldNeedNetworkFor方法根据情况进行修改,或者直接返回true;
                if (VDBG) log("  needNetworkFor");
                needNetworkFor(n.request, n.score);
                n.requested = true;
            } else if (shouldReleaseNetworkFor(n)) {
                if (VDBG) log("  releaseNetworkFor");
                //releaseNetworkFor(n.request); //2、把执行网络释放的操作注释即可。
                //n.requested = false;
            } else {
                if (VDBG) log("  done");
            }
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    当然这两个部分的代码都修改是没问题的。
    最好也是这两部分都进行修改,避免后期连接不上的问题。
    Android13 系统上虽然目录不同了,但是就要两者都改,不然有bug!

    三、网络情况查看和验证

    1、通过adb查看网络

    主要命令:

    
    adb shell ifconfig //查看配置信息
    
    adb shell dumpsys connectivity  //查看连接情况,信息更详细,有Score等信息
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    比如adb shell ifconfig的部分信息,如下:
    
    C:\Users\liwenzhi>adb shell ifconfig
    
    wlan0     Link encap:Ethernet  HWaddr 20:32:33:91:23:9e  Driver usb
              inet addr:192.168.43.53  Bcast:192.168.43.255  Mask:255.255.255.0
              inet6 addr: 2409:8955:3848:1a7e:5123:75a1:44e9:d36b/64 Scope: Global
              RX bytes:89876 TX bytes:1597990
    
    ...
    
    eth0      Link encap:Ethernet  HWaddr 02:ad:36:01:8a:3d  Driver meson8b-dwmac
              inet addr:192.5.1.17  Bcast:192.5.1.255  Mask:255.255.255.0
              collisions:0 txqueuelen:1000
              RX bytes:1549861 TX bytes:1983944
              Interrupt:48
    
    
    C:\Users\liwenzhi>
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    这里wifi(wlan0)和有线网络(eth0)都存在ip,表示可以进行连接

    比如adb shell dumpsys connectivity的部分信息,如下:
    
    Active default network: 101
    
    Current Networks:
    //其中一个网络,有线网
      NetworkAgentInfo{ ni{[type: Ethernet[], state: CONNECTED/CONNECTED, reason: (unspecified), extra: 02:ad:36:01:8a:3d, failover: false,
          available: true, roaming: false]}  network{100}  nethandle{432902426637}  lp{{InterfaceName: eth0 LinkAddresses: [ fe80::5f92:6ddf:1843:9ffa/64,192.5.1.6/24 ]    
          Requests: REQUEST:0 LISTEN:3 BACKGROUND_REQUEST:0 total:3
          NetworkRequest [ LISTEN id=4, [ Capabilities: FOREGROUND AdministratorUids: [] RequestorUid: 1000 RequestorPackageName: android] ]
          NetworkRequest [ LISTEN id=5, [ Capabilities: NOT_RESTRICTED&TRUSTED&NOT_VPN&FOREGROUND Uid: 1000 AdministratorUids: [] RequestorUid: 1000 RequestorPackageName: android] ]
          NetworkRequest [ LISTEN id=7, [ Capabilities: NOT_RESTRICTED&TRUSTED&NOT_VPN Uid: 1000 AdministratorUids: [] RequestorUid: 1000 RequestorPackageName: android] ]
        Lingered: //之前的请求信息(不是当前的)
          NetworkRequest [ REQUEST id=1, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN AdministratorUids: [] RequestorUid: 1000 RequestorPackageName: android] ], expires 24995ms
          NetworkRequest [ TRACK_DEFAULT id=8, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED Uid: 1000 AdministratorUids: [] RequestorUid: 1000 RequestorPackageName: android] ], expires 24995ms
    
    //另一个网络,wifi
      NetworkAgentInfo{ ni{[type: WIFI[], state: CONNECTED/CONNECTED, reason: (unspecified), extra: , failover: false,
          available: true, roaming: false]}  network{101}  nethandle{437197393933}  lp{{InterfaceName: wlan0 LinkAddresses: [ fe80::bbbb:2be7:6b3f:67da/64,192.5.1.27/24 ] DnsAddresses: [ /192.5.1.1 ]     
          Requests: REQUEST:2 LISTEN:8 BACKGROUND_REQUEST:0 total:10
          NetworkRequest [ REQUEST id=1, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN AdministratorUids: [] RequestorUid: 1000 RequestorPackageName: android] ]
          NetworkRequest [ LISTEN id=4, [ Capabilities: FOREGROUND AdministratorUids: [] RequestorUid: 1000 RequestorPackageName: android] ]
          NetworkRequest [ LISTEN id=5, [ Capabilities: NOT_RESTRICTED&TRUSTED&NOT_VPN&FOREGROUND Uid: 1000 AdministratorUids: [] RequestorUid: 1000 RequestorPackageName: android] ]
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    NetworkAgentInfo 表示一个网络

    像上面这种情况,默认使用的是wifi网络;
    如果wifi和有线网络不在同一个网段的情况,
    可以在adb shell里面直接ping通连接通同一个wifi网段的其他ip,但是ping不通同一个有线网络网段的ip;

    但是可以通过指定网络端口进行连接 ping -I NetName ip

    2、通过ping 命令查看网络是否连通

    主要命令:

    adb shell
    //使用wifi 网络访问某个网址
    ping -I wlan0 XXX.XXX.XXX.XXX
    //使用有线网网络访问某个网址
    ping -I eht0 XXX.XX.XXX.XXX
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    有线网和wifi可以一个连接局域网,一个连接手机热点网络
    或者一个连接内网,一个连接VPN网络。

    https://ip.bczs.net 网址可以查询国外网址的ip

    比如浏览器输入:

    https://ip.bczs.net/www.youtube.com
    
    
    • 1
    • 2

    网页就会显示:

    您查询的 域名:www.youtube.com --> 142.250.204.110
    所属国家/地区:美国(US)
    路由信息:142.250.204.0/24
    区域号码:AS15169
    区域名称:GOOGLE
    描述信息:
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    比如这里测试,有线网eth0 接入的是公司内网,wifi连接的是VPN路由器网络:

    130|console:/ # 
    130|console:/ #  //有线网 测试连接 YouTube,无法连通
    130|console:/ # ping -I eth0 172.217.24.78                                     
    PING 172.217.24.78 (172.217.24.78) from 192.168.31.71 eth0: 56(84) bytes of data.
    
    
    ^C
    --- 172.217.24.78 ping statistics ---
    5 packets transmitted, 0 received, 100% packet loss, time 4054ms
    
    1|console:/ # 
    1|console:/ # //vpn wifi 测试连接 YouTube,正常连通
    1|console:/ # ping -I wlan0 172.217.24.78                                      
    PING 172.217.24.78 (172.217.24.78) from 192.5.1.8 wlan0: 56(84) bytes of data.
    64 bytes from 172.217.24.78: icmp_seq=1 ttl=53 time=134 ms
    64 bytes from 172.217.24.78: icmp_seq=2 ttl=53 time=27.5 ms
    64 bytes from 172.217.24.78: icmp_seq=3 ttl=53 time=46.5 ms
    64 bytes from 172.217.24.78: icmp_seq=4 ttl=53 time=41.0 ms
    64 bytes from 172.217.24.78: icmp_seq=5 ttl=53 time=29.3 ms
    ^C
    --- 172.217.24.78 ping statistics ---
    130|console:/ # ^C
    130|console:/ # ping -I wlan0 www.baidu.com    //vpn wifi 测试连接 baidu,正常连通                                 
    PING www.a.shifen.com (157.148.69.74) from 192.5.1.8 wlan0: 56(84) bytes of data.
    64 bytes from 157.148.69.74: icmp_seq=1 ttl=41 time=132 ms
    64 bytes from 157.148.69.74: icmp_seq=2 ttl=41 time=103 ms
    64 bytes from 157.148.69.74: icmp_seq=3 ttl=41 time=113 ms
    ^C
    --- www.a.shifen.com ping statistics ---
    7 packets transmitted, 7 received, 0% packet loss, time 6004ms
    rtt min/avg/max/mdev = 84.540/107.435/132.974/13.661 ms
    console:/ # 
    console:/ # 
    console:/ # ping -I eth0 www.baidu.com   //有线网 测试连接baidu,正常连通                                      
    PING www.a.shifen.com (157.148.69.74) from 192.168.31.71 eth0: 56(84) bytes of data.
    64 bytes from 157.148.69.74: icmp_seq=1 ttl=48 time=14.2 ms
    64 bytes from 157.148.69.74: icmp_seq=2 ttl=48 time=13.5 ms
    64 bytes from 157.148.69.74: icmp_seq=3 ttl=48 time=13.6 ms
    64 bytes from 157.148.69.74: icmp_seq=4 ttl=48 time=13.6 ms
    ^C
    --- www.a.shifen.com ping statistics ---
    4 packets transmitted, 4 received, 0% packet loss, time 3004ms
    rtt min/avg/max/mdev = 13.511/13.768/14.231/0.309 ms
    console:/ # 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    可以看到连接VPN网络的wifi 是可以正常访问外网,公司内网无法访问外网!百度网页是内网和外网都可以正常联通的。
    证明有线网和wifi 是有区分的,并且都是可以正常访问外部和被外部访问的。

  • 相关阅读:
    陇剑杯2023线上wp
    day36-IO流03
    制作一个简单HTML传统端午节日网页(HTML+CSS)
    Excel和图片如何互相转换?有何技巧?
    谷粒学院16万字笔记+1600张配图(十三)——搭建前台环境、首页数据显示
    Windows MFC 工程应用开发与框架原理完全剖析视频教程(上)
    Redis 的网络框架是实现了 Reactor 模型吗?
    2023CSP-S初赛复习整理
    Lilliefors正态性检验
    重新认识下JVM级别的本地缓存框架Guava Cache——优秀从何而来
  • 原文地址:https://blog.csdn.net/wenzhi20102321/article/details/133913924