Android通过反射EthernetManager Api设置以太网为静态IP地址或者动态获取IP
Posted Code-Porter
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android通过反射EthernetManager Api设置以太网为静态IP地址或者动态获取IP相关的知识,希望对你有一定的参考价值。
一、对于一些工控行业的android主板一般都会扩展个以太网接口,也就是可以插网线进行上网;然后在系统设置页面有个以太网菜单可以进行IP、网关等设置,如下:
二、那怎么通过代码去设置呢?
1、Android系统在Framework层是有提供操作以太网Api的也就是android.net.EthernetManager
,但是Google把Api给隐藏了;所以最终你是调用不了的
2、那需要怎么操作才能调用到隐藏的Api呢?相信你肯定会立马想到使用反射去调用;对,没错!这里我就是使用的这个方式;当然如果你公司系统层也是自己搞的话就更简单了
三、先假装如果可以调用到android.net.EthernetManager
的Api,那么代码应该怎么写呢?
-
设置静态IP地址, new LinkAddress()报错是因为源码@hide了
-
设置动态ip地址
四、接下来就是通反射去调用了,代码量就比上面多的多了
/**
* 文件名: EthernetUtil
* 创建时间: 2020/8/21 on 11:22
* 描述: TODO 设置以太网静态ip 动态ip地址
*
* @author 阿钟
*/
public class EthernetUtil
/**
* 设置以太网动态获取IP
*/
public static boolean setDynamicIp(Context context)
try
Class<?> ethernetManagerCls = Class.forName("android.net.EthernetManager");
//获取EthernetManager实例
Object ethManager = context.getSystemService("ethernet");
//创建IpConfiguration
Class<?> ipConfigurationCls = Class.forName("android.net.IpConfiguration");
Object ipConfiguration = ipConfigurationCls.newInstance();
//获取ipAssignment、proxySettings的枚举值
Map<String, Object> ipConfigurationEnum = getIpConfigurationEnum(ipConfigurationCls);
//设置ipAssignment
Field ipAssignment = ipConfigurationCls.getField("ipAssignment");
ipAssignment.set(ipConfiguration, ipConfigurationEnum.get("IpAssignment.DHCP"));
//设置proxySettings
Field proxySettings = ipConfigurationCls.getField("proxySettings");
proxySettings.set(ipConfiguration, ipConfigurationEnum.get("ProxySettings.NONE"));
//获取EthernetManager的setConfiguration()
Method setConfigurationMethod = ethernetManagerCls.getDeclaredMethod("setConfiguration", ipConfiguration.getClass());
//设置动态IP
setConfigurationMethod.invoke(ethManager, ipConfiguration);
return true;
catch (Exception e)
e.printStackTrace();
return false;
/**
* 设置以太网静态IP地址
*
* @param address ip地址
* @param mask 子网掩码
* @param gate 网关
* @param dns dns
*/
public static boolean setEthernetStaticIp(Context context, String address, String mask, String gate, String dns)
try
Class<?> ethernetManagerCls = Class.forName("android.net.EthernetManager");
//获取EthernetManager实例
Object ethManager = context.getSystemService("ethernet");
//创建StaticIpConfiguration
Object staticIpConfiguration = newStaticIpConfiguration(address, gate, mask, dns);
//创建IpConfiguration
Object ipConfiguration = newIpConfiguration(staticIpConfiguration);
//获取EthernetManager的setConfiguration()
Method setConfigurationMethod = ethernetManagerCls.getDeclaredMethod("setConfiguration", ipConfiguration.getClass());
//保存静态ip设置
saveIpSettings(context, address, mask, gate, dns);
//设置静态IP
setConfigurationMethod.invoke(ethManager, ipConfiguration);
return true;
catch (Exception e)
e.printStackTrace();
return false;
/**
* 获取StaticIpConfiguration实例
*/
private static Object newStaticIpConfiguration(String address, String gate, String mask, String dns) throws Exception
Class<?> staticIpConfigurationCls = Class.forName("android.net.StaticIpConfiguration");
//实例化StaticIpConfiguration
Object staticIpConfiguration = staticIpConfigurationCls.newInstance();
Field ipAddress = staticIpConfigurationCls.getField("ipAddress");
Field gateway = staticIpConfigurationCls.getField("gateway");
Field domains = staticIpConfigurationCls.getField("domains");
Field dnsServers = staticIpConfigurationCls.getField("dnsServers");
//设置ipAddress
ipAddress.set(staticIpConfiguration, newLinkAddress(address, mask));
//设置网关
gateway.set(staticIpConfiguration, InetAddress.getByName(gate));
//设置掩码
domains.set(staticIpConfiguration, mask);
//设置dns
ArrayList<InetAddress> dnsList = (ArrayList<InetAddress>) dnsServers.get(staticIpConfiguration);
dnsList.add(InetAddress.getByName(dns));
return staticIpConfiguration;
/**
* 获取LinkAddress实例
*/
private static Object newLinkAddress(String address, String mask) throws Exception
Class<?> linkAddressCls = Class.forName("android.net.LinkAddress");
Constructor<?> linkAddressConstructor = linkAddressCls.getDeclaredConstructor(InetAddress.class, int.class);
return linkAddressConstructor.newInstance(InetAddress.getByName(address), getPrefixLength(mask));
/**
* 获取IpConfiguration实例
*/
private static Object newIpConfiguration(Object staticIpConfiguration) throws Exception
Class<?> ipConfigurationCls = Class.forName("android.net.IpConfiguration");
Object ipConfiguration = ipConfigurationCls.newInstance();
//设置StaticIpConfiguration
Field staticIpConfigurationField = ipConfigurationCls.getField("staticIpConfiguration");
staticIpConfigurationField.set(ipConfiguration, staticIpConfiguration);
//获取ipAssignment、proxySettings的枚举值
Map<String, Object> ipConfigurationEnum = getIpConfigurationEnum(ipConfigurationCls);
//设置ipAssignment
Field ipAssignment = ipConfigurationCls.getField("ipAssignment");
ipAssignment.set(ipConfiguration, ipConfigurationEnum.get("IpAssignment.STATIC"));
//设置proxySettings
Field proxySettings = ipConfigurationCls.getField("proxySettings");
proxySettings.set(ipConfiguration, ipConfigurationEnum.get("ProxySettings.STATIC"));
return ipConfiguration;
/**
* 获取IpConfiguration的枚举值
*/
private static Map<String, Object> getIpConfigurationEnum(Class<?> ipConfigurationCls)
Map<String, Object> enumMap = new HashMap<>();
Class<?>[] enumClass = ipConfigurationCls.getDeclaredClasses();
for (Class<?> enumC : enumClass)
Object[] enumConstants = enumC.getEnumConstants();
if (enumConstants == null) continue;
for (Object enu : enumConstants)
enumMap.put(enumC.getSimpleName() + "." + enu.toString(), enu);
return enumMap;
/**
* 保存静态ip设置
*/
private static void saveIpSettings(Context context, String address, String mask, String gate, String dns)
ContentResolver contentResolver = context.getContentResolver();
Settings.Global.putString(contentResolver, "ethernet_static_ip", address);
Settings.Global.putString(contentResolver, "ethernet_static_mask", mask);
Settings.Global.putString(contentResolver, "ethernet_static_gateway", gate);
Settings.Global.putString(contentResolver, "ethernet_static_dns1", dns);
/**
* 获取长度
*/
private static int getPrefixLength(String mask)
String[] strs = mask.split("\\\\.");
int count = 0;
for (String str : strs)
if (str.equals("255"))
++count;
return count * 8;
- 使用只需调用方法即可:
//设置静态ip
EthernetUtil.setEthernetStaticIp(context, "192.168.5.33", "255.255.255.0", "192.168.5.1", "8.8.8.8");
//设置动态获取ip
EthernetUtil.setDynamicIp(context)
最后:这个代码本人在Android7.0的原生系统验证是可以使用的,有需要的可以使用试试EthernetUtil源码下载地址
- 最后在推荐个好用的系统源码查看网址吧:Android 系统源码在线查看
以上是关于Android通过反射EthernetManager Api设置以太网为静态IP地址或者动态获取IP的主要内容,如果未能解决你的问题,请参考以下文章
小花招解决Android 9 Pie 不能反射隐藏API限制
Android 插件化Hook 插件化框架 ( 通过反射获取 “插件包“ 中的 Element[] dexElements )
Android 插件化Hook 插件化框架 ( 通过反射获取 “宿主“ 应用中的 Element[] dexElements )