Android M 多网络应用

xiaoxiao2021-02-28  74

达到 android6.0 wifi连接外网,ethernet连接内网局域网  1、修改 framework 层代码,使得 wif 和 ethernet 同时存在  由于我们的目标时wifi连接外网,ethernet访问特定局域网,所有设置 wifi 优先,ethernet 进行单独配置。

修改wifi优先,在 NetworkAgentInfo.Java的方法getCurrentScore() 中加入:  if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {  return MAXIMUM_NETWORK_SCORE;  }  这样 wifi 的分值就最高了。

修改 wifi 连接上的情况下,插入有线会主动连接。由于上面将 wifi 的优先级调到最高了,所有插入有线时,  判断当前网络连接优先级高于有线,所以不会主动连接有线。在 EthernetNetworkFactory.java的方法 updateInterfaceState  中加入  mFactory.setScoreFilter(up ? NETWORK_SCORE : -1);  if (up) {  mFactory.startNetwork();  }  这样只有已插入网线就会主动去连接

还是由于wifi优先,如果先连接有线再打开wifi,去连接wifi时会关闭有线。这个时候需要修改 ConnectivityService.java中的方法  private void teardownUnneededNetwork(NetworkAgentInfo nai) {  /*for (int i = 0; i < nai.networkRequests.size(); i++) {  NetworkRequest nr = nai.networkRequests.valueAt(i);  // Ignore listening requests.  if (!isRequest(nr)) continue;  loge(“Dead network still had at least ” + nr);  break;  }  nai.asyncChannel.disconnect();*/  }  这样就不会去关闭其他连接了。

经过以上的修改,达到了 wifi 和 ethernet 同时存在,而且 wifi 优先正常访问外网的目的。

2、wifi 和 ethernet 同时存在,考虑配置静态路由使得 ethernet 访问指定网络。  修改 dhcpcd.c 中的 main 方法,可以使 dhcp 服务器下发的静态路由添加到路由表中。  case ‘a’:  syslog(LOG_INFO, “avoid_routes one %d”, avoid_routes);  //avoid_routes = 1;  syslog(LOG_INFO, “avoid_routes two %d”, avoid_routes);  break;

此时用 route 命令查看,可以看到路由表中多了一条 192.168.10.0 192.168.2.1 255.255.255.0 UG 202 0 0 eth0  :/ # route  Kernel IP routing table  Destination Gateway Genmask Flags Metric Ref Use Iface  192.168.2.0 * 255.255.255.0 U 202 0 0 eth0  192.168.3.0 * 255.255.255.0 U 0 0 0 wlan0  192.168.10.0 192.168.2.1 255.255.255.0 UG 202 0 0 eth0

但是实际上此路由表不会起到任何作用。因为在 android6.0 开始使用了策略路由,如下是 wifi 和 ethernet 同时连接情况下的 策略路由信息

:/ # ip rule list  0: from all lookup local  10000: from all fwmark 0xc0000/0xd0000 lookup legacy_system  10500: from all oif wlan0 uidrange 0-0 lookup wlan0  10500: from all oif eth0 uidrange 0-0 lookup eth0  13000: from all fwmark 0x10063/0x1ffff lookup local_network  13000: from all fwmark 0x10065/0x1ffff lookup wlan0  13000: from all fwmark 0x10066/0x1ffff lookup eth0  14000: from all oif wlan0 lookup wlan0  14000: from all oif eth0 lookup eth0  15000: from all fwmark 0x0/0x10000 lookup legacy_system  16000: from all fwmark 0x0/0x10000 lookup legacy_network  17000: from all fwmark 0x0/0x10000 lookup local_network  19000: from all fwmark 0x65/0x1ffff lookup wlan0  19000: from all fwmark 0x66/0x1ffff lookup eth0  22000: from all fwmark 0x0/0xffff lookup wlan0  23000: from all fwmark 0x0/0xffff uidrange 0-0 lookup main  32000: from all unreachable

同时可以看到 route 命令查看的实际上是 main 路由表的路由信息  :/ # ip route list table main  192.168.2.0/24 dev eth0 proto kernel scope link src 192.168.2.247 metric 202  192.168.3.0/24 dev wlan0 proto kernel scope link src 192.168.3.146  192.168.10.0/24 via 192.168.2.1 dev eth0 metric 202

所以从上面的分析可以得出结论,单纯依靠 dhcp 下发静态路由,并不能到达效果。

3、android6.0 策略路由  :/ # ip rule list  0: from all lookup local  10000: from all fwmark 0xc0000/0xd0000 lookup legacy_system  10500: from all oif wlan0 uidrange 0-0 lookup wlan0  10500: from all oif eth0 uidrange 0-0 lookup eth0  13000: from all fwmark 0x10063/0x1ffff lookup local_network  13000: from all fwmark 0x10065/0x1ffff lookup wlan0  13000: from all fwmark 0x10066/0x1ffff lookup eth0  14000: from all oif wlan0 lookup wlan0  14000: from all oif eth0 lookup eth0  15000: from all fwmark 0x0/0x10000 lookup legacy_system  16000: from all fwmark 0x0/0x10000 lookup legacy_network  17000: from all fwmark 0x0/0x10000 lookup local_network  19000: from all fwmark 0x65/0x1ffff lookup wlan0  19000: from all fwmark 0x66/0x1ffff lookup eth0  22000: from all fwmark 0x0/0xffff lookup wlan0  23000: from all fwmark 0x0/0xffff uidrange 0-0 lookup main  32000: from all unreachable

从这个路由规则中可以看到, 路由表 local优先,然后是netid 对应 0x10065 的走 wlan0 路由表,对应 0x10066 走 eth0 路由表。  而通常情况下访问网络时没有设置 netid,默认就使用 22000: from all fwmark 0x0/0xffff lookup wlan0 这个,即 wlan0 路由表。  netid 指定在 android6.0中应用可以通过 bindProcessToNetwork() 来指定使用wlan或者ethernet进行网络访问。

看下各个路由表中的信息:  :/ # ip route list table wlan0  default via 192.168.3.1 dev wlan0 proto static  192.168.3.0/24 dev wlan0 proto static scope link

:/ # ip route list table eth0  default via 192.168.2.1 dev eth0 proto static  192.168.2.0/24 dev eth0 proto static scope link

以上静态路由无法达到目的,策略路由不知道如何通过dhcp配置,而且就算配置也只能对应在 eth0 表中,但起作用的是 wlan0 这个路由表。  所以这条路放弃,换个思路。

4、自由选择要使用的网络  13000: from all fwmark 0x10066/0x1ffff lookup eth0 看这条路由信息,可以想到如果对应 app 在访问指定网络时设置 netid 为 0x10066,是否就可以用 eth0 访问指定网络。  接着 android6.0 的网络相关的新功能, bindProcessToNetwork 接口。  详细使用可以参照原生代码中 CaptivePortalLoginActivity 类。

这个调用的过程可以参考 http://blog.csdn.net/javon_hzw/article/details/46831771

转载请注明原文地址: https://www.6miu.com/read-82732.html

最新回复(0)