Android应用网络限制功能实现
2017-09-19 20:39
267 查看
在之前的博文Android防火墙功能实现与原理分析中分析了Android防火墙实现原理,这里继续讲解Android 应用网络限制实现流程。
先看看需求:现在4G流量费用比较昂贵,为了避免流量的消耗,我们可以限制某个应用连接网络,或者限制某个app只能使用wifi等等。
再看看效果图:
当我们使用流量上网时,会发现此时谷歌浏览器无法连接网络,这就达到了我们的目的。
不多说,直接上代码。
1.第一步:我们需要把我们控制网络的方法声明在frameworks/base/core/Java/android/os/INetworkManagementService.aidl中:
第二步:在frameworks/base/services/core/java/com/android/server目录下的NetworkManagementService.java中实现我们声明的两个方法:
第三步:下面又通过socket通信方式调用到system/netd层的system/netd/server目录下的CommandListener.cpp中添加如下:
然后在int CommandListener::FirewallCmd::runCommand()中添加:
上面代码又调用到system/netd/server目录下的FirewallController.cpp的方法,添加的方法如下:
上面添加的方法声明在system/netd/server目录下的FirewallController.h中:
第四步:调用方法实现防火墙功能:
这里只要传递应用的uid进去就可以实现。
获取uid的方式:
先看看需求:现在4G流量费用比较昂贵,为了避免流量的消耗,我们可以限制某个应用连接网络,或者限制某个app只能使用wifi等等。
再看看效果图:
当我们使用流量上网时,会发现此时谷歌浏览器无法连接网络,这就达到了我们的目的。
不多说,直接上代码。
1.第一步:我们需要把我们控制网络的方法声明在frameworks/base/core/Java/android/os/INetworkManagementService.aidl中:
interface INetworkManagementService { …… void setMobileDataUidRule(int uid, boolean allow); void setWifiDataUidRule(int uid, boolean allow); …… }
第二步:在frameworks/base/services/core/java/com/android/server目录下的NetworkManagementService.java中实现我们声明的两个方法:
//add by xiaoxsen public void setMobileDataUidRule(int uid, boolean allow) { enforceSystemUid();//check try { final String rule = allow ? "allow" : "deny"; mConnector.execute("firewall", "set_mobile_data_uid_rule", uid, rule); } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); } } public void setWifiDataUidRule(int uid, boolean allow) { enforceSystemUid(); try { final String rule = allow ? "allow" : "deny"; mConnector.execute("firewall", "set_wifi_data_uid_rule", uid, rule); } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); } } //add by xiaoxsen
第三步:下面又通过socket通信方式调用到system/netd层的system/netd/server目录下的CommandListener.cpp中添加如下:
CommandListener::CommandListener() : FrameworkListener("netd", true) { //add by xiaoxsen sFirewallCtrl->initIptableFirewall();// 开机初始化 //add by xiaoxsen ....... }
然后在int CommandListener::FirewallCmd::runCommand()中添加:
//add by xiaoxsen if (!strcmp(argv[1], "set_mobile_data_uid_rule")) { if (argc != 4) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: firewall set_mobile_data_uid_rule <1000> <allow|deny>", false); return 0; } int uid = atoi(argv[2]); FirewallRule rule = parseRule(argv[3]); int res = sFirewallCtrl->setMobileDataUidRule(uid, rule); return sendGenericOkFail(cli, res); } if (!strcmp(argv[1], "set_wifi_data_uid_rule")) { if (argc != 4) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: firewall set_wifi_data_uid_rule <1000> <allow|deny>", false); return 0; } int uid = atoi(argv[2]); FirewallRule rule = parseRule(argv[3]); int res = sFirewallCtrl->setWifiDataUidRule(uid, rule); return sendGenericOkFail(cli, res); } //add by xiaoxsen
上面代码又调用到system/netd/server目录下的FirewallController.cpp的方法,添加的方法如下:
#include <cutils/properties.h> //add by xiaoxsen const char* op_3g; const char* op_wifi; . . . int FirewallController::initIptableFirewall(void) { int res = 0; op_3g = "ccmni+"; //网络端口 op_wifi = "wlan0";//wifi网络端口 //查看网络端口的方法: //1.输入adb shell //2.输入netcfg // 新建一个drop_wall链表 res |= execIptables(V4V6, "-w", "-N", "drop_wall", NULL); // 把新建的drop_wall链表添加到OUTPUT链表目录下 res |= execIptables(V4V6, "-w", "-A", "OUTPUT", "-j", "drop_wall", NULL); } int FirewallController::setMobileDataUidRule(int uid, FirewallRule rule) { char uidStr[16]; sprintf(uidStr, "%d", uid); const char* op; if (rule == ALLOW) { op = "-D";// 删除链表中的规则 } else { op = "-A";// 添加规则到链表 } int res = 0; res |= execIptables(V4V6, "-w", op, "drop_wall", "-o", op_3g, "-m", "owner", "--uid-owner", uidStr, "-j", "REJECT", NULL); return res; } int FirewallController::setWifiDataUidRule(int uid, FirewallRule rule) { char uidStr[16]; sprintf(uidStr, "%d", uid); const char* op; if (rule == ALLOW) { op = "-D";// 删除链表中的规则 } else { op = "-A";// 添加规则到链表 } int res = 0; res |= execIptables(V4V6, "-w", op, "drop_wall", "-o", op_wifi, "-m", "owner", "--uid-owner", uidStr, "-j", "REJECT", NULL); return res; } //add by xiaoxsen
上面添加的方法声明在system/netd/server目录下的FirewallController.h中:
class FirewallController { public: . . . //add by xiaoxsen int initIptableFirewall(void); int setMobileDataUidRule(int, FirewallRule); int setWifiDataUidRule(int, FirewallRule); //add by xiaoxsen . . . }
第四步:调用方法实现防火墙功能:
networkManagementService = INetworkManagementService. Stub.asInterface(ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE)); if (networkManagementService != null) { networkManagementService. setMobileDataUidRule (10038,true); networkManagementService. setWifiDataUidRule (10048, true); }
这里只要传递应用的uid进去就可以实现。
获取uid的方式:
List<AppdataInfo> installApplictionList = new ArrayList<AppdataInfo>(); pm = mContext.getPackageManager(); List<ApplicationInfo> installedApplications = pm.getInstalledApplications(PackageManager.GET_META_DATA); for (ApplicationInfo applicationInfo : installedApplications) { if (applicationInfo != null && PackageManager.PERMISSION_GRANTED == pm .checkPermission(Manifest.permission.INTERNET, applicationInfo.packageName)) { //这样就能获取到有网络权限应用的uid int uid = applicationInfo.uid }
相关文章推荐
- Android应用中保存网络图片功能实现详解
- Android应用如何实现换肤功能
- Android应用如何实现换肤功能
- Android应用自动更新功能的实现!!!
- Android应用如何实现换肤功能
- Android应用自动更新功能的实现!!!
- Android应用之个人应用软件开发(3)【SQLite数据库及理财功能实现】
- Android应用自动更新功能的代码实现
- Android应用自动更新功能的代码实现
- Android应用自动更新功能的实现!!! .(转自魏祝林博客)
- Android应用自动更新功能的实现!!!
- Android下的应用编程——用HTTP协议实现文件上传功能
- Android应用自动更新功能的代码实现
- Android应用自动更新功能的实现!!!
- Android应用如何实现换肤功能
- Android应用自动更新功能的代码实现
- Android应用如何实现换主题功能
- Android应用自动更新功能的实现!!!
- AIR Native Extension:在Android的Flex应用中调用Android Intent实现分享功能
- Android应用如何实现换肤功能