android系统同时使用wifi和4g上网

版本信息: 
android5.1.1 
Linux version 3.10.49

需求:通过4g访问外网,同时通过wifi访问内网。 
 android系统默认情况下,wifi连网时,4g数据链接会被强制断开,但实际有需要wifi和4g同时上网,为了满足这个要求,需要修改android的网络管理机制。 
 首先实现wifi连网时,不让4g数据链接被强制断开: 
 修改  frameworks/base/services/core/java/com/android/server/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();
    }把nai.asyncChannel.disconnect(); 行mark掉。这样wifi连网,4g数据链接不会被强制断开了。 

  $ netcfg 
rmnet0 UP 0.0.0.0/0 0x00000041 00:00:00:00:00:00 
r_rmnet_data8 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00 
r_rmnet_data7 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00 
r_rmnet_data5 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00 
r_rmnet_data6 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00 
r_rmnet_data4 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00 
r_rmnet_data3 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00 
r_rmnet_data1 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00 
r_rmnet_data2 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00 
r_rmnet_data0 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00 
rmnet_data4 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00 
rmnet_data2 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00 
rmnet_data3 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00 
rmnet_data1 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00 
rmnet_data0 UP 10.66.94.93/30 0x00000041 00:00:00:00:00:00 
rmnet_data7 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00 
rmnet_data5 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00 
rmnet_data6 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00 
wlan0 UP 192.168.10.10/24 0x00001043 34:87:3d:31:e4:77 
sit0 DOWN 0.0.0.0/0 0x00000080 00:00:00:00:00:00 
p2p0 UP 0.0.0.0/0 0x00001003 36:87:3d:31:e4:77 
lo UP 127.0.0.1/8 0x00000049 00:00:00:00:00:00 
dummy0 DOWN 0.0.0.0/0 0x00000082 d6:d1:38:38:ed:c8

  但此时,网络访问默认还是走wifi通道,把wifi AP与外网断开,ping下192.168.10.1可以ping通,但www.baidu.com会发现ping不通, 
  指定network,再ping 
  ping -I rmnet_data0 www.baidu.com   
  会发现可以ping通,说明此时wifi和4g都已经连上网了。 

  APP程序可以通过setProcessDefaultNetwork把进程和network绑定来访问特定网络。

https://yq.aliyun.com/articles/341803

https://blog.csdn.net/wr132/article/details/78429159

/*修改外置摄像头只能通过wifi上网  begin 20180619*/

import android.net.ConnectivityManager;
import android.content.Context;
import android.net.NetworkRequest;
import android.net.NetworkCapabilities;
import android.net.Network;
/*修改外置摄像头只能通过wifi上网  end 20180619*/

/*修改外置摄像头只能通过wifi上网  begin 20180619*/
//设置该APP只能通过wifi传输数据
public void setwifiNet(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(
Context.CONNECTIVITY_SERVICE);
NetworkRequest.Builder req = new NetworkRequest.Builder();
//req.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
// 设置指定的网络传输类型 wifi
req.addTransportType(NetworkCapabilities.TRANSPORT_WIFI );
cm.requestNetwork(req.build(), new ConnectivityManager.NetworkCallback() {


@Override
public void onAvailable(Network network) {
try {
/*if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
ConnectivityManager.setProcessDefaultNetwork(network);
} else {
connectivityManager.bindProcessToNetwork(network);
}*/
//if (Build.VERSION.SDK_INT >= 23) {   
      // cm.bindProcessToNetwork(network);
     //} else {   
       // 23后这个方法舍弃了  

       ConnectivityManager.setProcessDefaultNetwork(network);
     //}
} catch (IllegalStateException e) {
Log.e(TAG, "ConnectivityManager.NetworkCallback.onAvailable: ", e);
}
}


// Be sure to override other options in NetworkCallback() too...
});
}
/*修改外置摄像头只能通过wifi上网  end 20180619*/

但我们的要求是一个APP有的数据走wifi有的数据走4g,不希望APP和某个network绑定,这样就是要求默认走4g上网,访问内网ip则走wifi.即修改系统让4g的优先级优于wifi,修改route rule,使得访问内网ip时,则走wifi. 

 修改系统让4g的优先级优于wifi

android5.1是依据网络评分来评定网络的优先级,默认情况下,wifi的评分比4g高。可以修改 

修改网络连接优先级为

Ethernet > Mobile > Wifi


修改

[java]  view plain  copy
  1. diff --git a/frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DataConnection.java b/frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DataConnection.java  
  2. old mode 100644  
  3. new mode 100755  
  4. index 09b3c9b..00fba2a  
  5. --- a/frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DataConnection.java  
  6. +++ b/frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DataConnection.java  
  7. @@ -1734,7 +1734,7 @@ public final class DataConnection extends StateMachine {  
  8.              misc.subscriberId = mPhone.getSubscriberId();  
  9.              mNetworkAgent = new DcNetworkAgent(getHandler().getLooper(), mPhone.getContext(),  
  10.                      "DcNetworkAgent", mNetworkInfo, makeNetworkCapabilities(), mLinkProperties,  
  11. -                    50, misc);  
  12. +                    100, misc);  
  13.          }  
  14.    
  15.          @Override  
  16. diff --git a/frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DctController.java b/frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DctController.java  
  17. old mode 100644  
  18. new mode 100755  
  19. index 4fce2ec..fdb59b1  
  20. --- a/frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DctController.java  
  21. +++ b/frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DctController.java  
  22. @@ -152,7 +152,7 @@ public class DctController extends Handler {  
  23.          mNetworkFactory[index] = new TelephonyNetworkFactory(this.getLooper(),  
  24.                  mPhones[index].getContext(), "TelephonyNetworkFactory", phoneBase,  
  25.                  mNetworkFilter[index]);  
  26. -        mNetworkFactory[index].setScoreFilter(50);  
  27. +        mNetworkFactory[index].setScoreFilter(100);  
  28.          mNetworkFactoryMessenger[index] = new Messenger(mNetworkFactory[index]);  
  29.          cm.registerNetworkFactory(mNetworkFactoryMessenger[index], "Telephony");  
  30.      }  

说明

网络优先级采用新的score机制.

以上改法, 将移动网络的score从50 加到 100.

从当前代码中看, Ethernet (150), Wifi(60)

frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java(Wifi)

[java]  view plain  copy
  1. mNetworkAgent = new WifiNetworkAgent(getHandler().getLooper(), mContext,  
  2.         "WifiNetworkAgent", mNetworkInfo, mNetworkCapabilitiesFilter,  
  3.         mLinkProperties, 60);  

[java]  view plain  copy
  1. mNetworkFactory = new WifiNetworkFactory(getHandler().getLooper(), mContext,  
  2.         NETWORKTYPE, mNetworkCapabilitiesFilter);  
  3. mNetworkFactory.setScoreFilter(60);  


frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java(Ethernet)

[java]  view plain  copy
  1. private static final int NETWORK_SCORE = 150;   
  2.                    // Create our NetworkAgent.  
  3.                     mNetworkAgent = new NetworkAgent(mFactory.getLooper(), mContext,  
  4.                             NETWORK_TYPE, mNetworkInfo, mNetworkCapabilities, mLinkProperties,  
  5.                             NETWORK_SCORE) { 

把4g网络评分强制改为100,这样可以确保总是大于wifi网络的评分。 
更新系统,ping www.baidu.com可以ping通,说明此时系统优先走4g网络(wifi AP与外网断开)。 ping 192.168.10.1 不通。

修改route rule:

查看默认route rule: 
ip rule 
0: from all lookup local 
10000: from all fwmark 0xc0000/0xd0000 lookup 99 
13000: from all fwmark 0x10063/0x1ffff lookup 97 
13000: from all fwmark 0x10064/0x1ffff lookup 1022 
13000: from all fwmark 0x10065/0x1ffff lookup 1005 
14000: from all oif wlan0 lookup 1022 
14000: from all oif rmnet_data0 lookup 1005 
15000: from all fwmark 0x0/0x10000 lookup 99 
16000: from all fwmark 0x0/0x10000 lookup 98 
17000: from all fwmark 0x0/0x10000 lookup 97 
19000: from all fwmark 0x64/0x1ffff lookup 1022 
19000: from all fwmark 0x65/0x1ffff lookup 1005 
22000: from all fwmark 0x0/0xffff lookup 1005 
23000: from all fwmark 0x0/0xffff uidrange 0-0 lookup main 
32000: from all unreachable

尝试添加一条route rule: 
ip rule add to 192.168.10.0/24 table wlan0 pref 100 
修改后route rule: 
0: from all lookup local 
100: from all to 192.168.10.0/24 lookup 1022 
10000: from all fwmark 0xc0000/0xd0000 lookup 99 
13000: from all fwmark 0x10063/0x1ffff lookup 97 
13000: from all fwmark 0x10064/0x1ffff lookup 1022 
13000: from all fwmark 0x10065/0x1ffff lookup 1005 
14000: from all oif wlan0 lookup 1022 
14000: from all oif rmnet_data0 lookup 1005 
15000: from all fwmark 0x0/0x10000 lookup 99 
16000: from all fwmark 0x0/0x10000 lookup 98 
17000: from all fwmark 0x0/0x10000 lookup 97 
19000: from all fwmark 0x64/0x1ffff lookup 1022 
19000: from all fwmark 0x65/0x1ffff lookup 1005 
22000: from all fwmark 0x0/0xffff lookup 1005 
23000: from all fwmark 0x0/0xffff uidrange 0-0 lookup main 
32000: from all unreachable

这样就可以直接ping 通192.168.10.1了。 
  
APP程序没有修改route rule的权限,我们想让系统在wifi连接AP后自动添加需要的一条route rule. 
可以修改netd (system/netd/server/),netd有权限修改route rule.

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
要监控Android设备的4G网络状态,可以使用Android系统提供的ConnectivityManager类。该类提供了网络连接状态的查询和监听功能。以下是一个示例代码,可以实时监测4G网络状态的变化: ```java ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_MOBILE && networkInfo.getSubtype() == TelephonyManager.NETWORK_TYPE_LTE) { // 4G网络已连接 } else { // 4G网络未连接 } // 监听网络连接状态变化 BroadcastReceiver connectivityReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_MOBILE && networkInfo.getSubtype() == TelephonyManager.NETWORK_TYPE_LTE) { // 4G网络已连接 } else { // 4G网络未连接 } } }; IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); registerReceiver(connectivityReceiver, filter); ``` 以上代码首先查询当前网络连接状态,如果当前网络类型为移动网络,并且子类型为LTE,则判定为4G网络已连接。然后注册一个广播接收器,用于监听网络连接状态变化事件,当网络状态变化时,重新查询当前网络连接状态,判断是否为4G网络
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值