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

但是我试了一下,在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");
        }
    }

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

三、网络情况查看和验证

1、通过adb查看网络

主要命令:


adb shell ifconfig //查看配置信息

adb shell dumpsys connectivity  //查看连接情况,信息更详细,有Score等信息

比如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>


这里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] ]

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

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

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

比如浏览器输入:

https://ip.bczs.net/www.youtube.com

网页就会显示:

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

比如这里测试,有线网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:/ # // 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    // 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:/ # 

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

你可能感兴趣的:(android,Android系统,网络,开发语言,android)