前提
只有系统APP才具备此功能,即APP的uid必须使用系统用户,APK必须进行系统签名
这个不懂的请翻阅本专栏前面的博客
核心代码
由于以太网相关接口是隐藏的,只能通过反射调用
package com.android.commons.framework;
import android.content.ContentResolver;
import android.content.Context;
import android.provider.Settings;
import com.easing.commons.android.code.Console;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import lombok.SneakyThrows;
@SuppressWarnings("all")
public class EthernetHandlerInternal {
//设置以太网动态IP
public static boolean setDynamicIp(Context context) {
try {
//创建EthernetManager实例
Class ethernetManagerClass = Class.forName("android.net.EthernetManager");
Object ethernetManager = context.getSystemService("ethernet");
//创建IpConfiguration
Class ipConfigurationClass = Class.forName("android.net.IpConfiguration");
Object ipConfiguration = ipConfigurationClass.newInstance();
//获取所有枚举常量
Map enumMap = getIpConfigurationEnumMap(ipConfigurationClass);
//设置ipAssignment
Field ipAssignment = ipConfigurationClass.getField("ipAssignment");
ipAssignment.set(ipConfiguration, enumMap.get("IpAssignment.DHCP"));
//设置proxySettings
Field proxySettings = ipConfigurationClass.getField("proxySettings");
proxySettings.set(ipConfiguration, enumMap.get("ProxySettings.NONE"));
//设置Configuration
Method setConfigurationMethod = ethernetManagerClass.getDeclaredMethod("setConfiguration", ipConfiguration.getClass());
setConfigurationMethod.invoke(ethernetManager, ipConfiguration);
return true;
} catch (Throwable e) {
Console.error(e);
return false;
}
}
//设置以太网静态IP
public static boolean setStaticIp(Context context, String address, String mask, String gateway, String dns) {
try {
//创建EthernetManager实例
Class ethernetManagerClass = Class.forName("android.net.EthernetManager");
Object ethernetManager = context.getSystemService("ethernet");
//设置IpConfiguration
Object staticIpConfiguration = newStaticIpConfiguration(address, gateway, mask, dns);
Object ipConfiguration = newIpConfiguration(staticIpConfiguration);
//保存IP设置
saveIpSettings(context, address, gateway, mask, dns);
//设置Configuration
Method setConfigurationMethod = ethernetManagerClass.getDeclaredMethod("setConfiguration", ipConfiguration.getClass());
setConfigurationMethod.invoke(ethernetManager, ipConfiguration);
return true;
} catch (Throwable e) {
Console.error(e);
return false;
}
}
//创建LinkAddress
@SneakyThrows
protected static Object newLinkAddress(String address, String mask) {
Class linkAddressClass = Class.forName("android.net.LinkAddress");
Constructor constructor = linkAddressClass.getDeclaredConstructor(InetAddress.class, int.class);
return constructor.newInstance(InetAddress.getByName(address), getPrefixLength(mask));
}
//创建StaticIpConfiguration
@SneakyThrows
protected static Object newStaticIpConfiguration(String address, String gateway, String mask, String dns) {
//创建StaticIpConfiguration
Class clazz = Class.forName("android.net.StaticIpConfiguration");
Object staticIpConfiguration = clazz.newInstance();
//设置IP
Field addressField = clazz.getField("ipAddress");
addressField.set(staticIpConfiguration, newLinkAddress(address, mask));
//设置网关
Field gatewayField = clazz.getField("gateway");
gatewayField.set(staticIpConfiguration, InetAddress.getByName(gateway));
//设置子网掩码
Field domainField = clazz.getField("domains");
domainField.set(staticIpConfiguration, mask);
//设置DNS
Field dnsField = clazz.getField("dnsServers");
List dnsList = (List) dnsField.get(staticIpConfiguration);
dnsList.add(InetAddress.getByName(dns));
return staticIpConfiguration;
}
//创建IpConfiguration
@SneakyThrows
protected static Object newIpConfiguration(Object staticIpConfiguration) {
//创建IpConfiguration
Class clazz = Class.forName("android.net.IpConfiguration");
Object ipConfiguration = clazz.newInstance();
//设置staticIpConfiguration
Field staticIpConfigurationField = clazz.getField("staticIpConfiguration");
staticIpConfigurationField.set(ipConfiguration, staticIpConfiguration);
Map ipConfigurationEnum = getIpConfigurationEnumMap(clazz);
//设置ipAssignment
Field ipAssignment = clazz.getField("ipAssignment");
ipAssignment.set(ipConfiguration, ipConfigurationEnum.get("IpAssignment.STATIC"));
//设置proxySettings
Field proxySettings = clazz.getField("proxySettings");
proxySettings.set(ipConfiguration, ipConfigurationEnum.get("ProxySettings.STATIC"));
return ipConfiguration;
}
//获取IpConfiguration类中的所有枚举常量
protected static Map getIpConfigurationEnumMap(Class ipConfigurationClass) {
Map enumMap = new LinkedHashMap();
Class[] classes = ipConfigurationClass.getDeclaredClasses();
for (Class clazz : classes) {
Object[] enumConstants = clazz.getEnumConstants();
if (enumConstants == null)
continue;
for (Object constant : enumConstants)
enumMap.put(clazz.getSimpleName() + "." + constant.toString(), constant);
}
return enumMap;
}
//保存IP设置
protected static void saveIpSettings(Context context, String address, String gateway, String mask, 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", gateway);
Settings.Global.putString(contentResolver, "ethernet_static_dns1", dns);
}
//根据子网掩码,自动计算前缀长度
protected static int getPrefixLength(String mask) {
String[] strs = mask.split("\\.");
int count = 0;
for (String str : strs)
if (str.equals("255"))
++count;
return count * 8;
}
}
package com.android.commons.framework;
import com.easing.commons.android.app.CommonApplication;
import com.easing.commons.android.code.Console;
import lombok.SneakyThrows;
@SuppressWarnings("all")
public class EthernetHandler {
//设置动态IP
@SneakyThrows
public static boolean setDynamicIP() {
try {
boolean ret = EthernetHandlerInternal.setDynamicIp(CommonApplication.ctx);
return ret;
} catch (Throwable e) {
Console.error(e);
return false;
}
}
//设置以太网静态IP
//子网掩码和DNS使用默认值
@SneakyThrows
public static boolean setStaticIP(String address, String gateway) {
try {
boolean ret = EthernetHandlerInternal.setStaticIp(CommonApplication.ctx, address, "255.255.255.0", gateway, "119.29.29.29");
return ret;
} catch (Throwable e) {
Console.error(e);
return false;
}
}
}