package com.rxgb.settings.utils;
import android.annotation.SuppressLint;
import android.content.Context;
import android.net.LinkAddress;
import android.util.Log;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
/**
* 配置以太网的工具类
*/
@SuppressWarnings({"unused", "ConstantConditions", "JavaReflectionMemberAccess"})
public class EthernetUtils {
private final String TAG = "EthernetUtils";
private final Object ethManager;
private final Method setConfigurationMethod;
private final Method getConfigurationMethod;
private final Method isAvailableMethod;
private final Method getIpAddressMethod;
private final Method getNetmaskMethod;
private final Method getGatewayMethod;
private final Method getDnsMethod;
private final Method getAvailableInterfacesMethod;
@SuppressLint({"WrongConstant", "SoonBlockedPrivateApi"})
public EthernetUtils(Context context) {
try {
@SuppressLint("PrivateApi")
Class> emClz = Class.forName("android.net.EthernetManager");
ethManager = context.getSystemService("ethernet");
@SuppressLint("PrivateApi")
Class> ipCnClz = Class.forName("android.net.IpConfiguration");
Object ipConfiguration = ipCnClz.newInstance();
setConfigurationMethod = emClz.getDeclaredMethod("setConfiguration", String.class, ipConfiguration.getClass());
getConfigurationMethod = emClz.getDeclaredMethod("getConfiguration", String.class);
isAvailableMethod = emClz.getDeclaredMethod("isAvailable", String.class);
getIpAddressMethod = emClz.getDeclaredMethod("getIpAddress", String.class);
getNetmaskMethod = emClz.getDeclaredMethod("getNetmask", String.class);
getGatewayMethod = emClz.getDeclaredMethod("getGateway", String.class);
getDnsMethod = emClz.getDeclaredMethod("getDns", String.class);
getAvailableInterfacesMethod = emClz.getDeclaredMethod("getAvailableInterfaces");
} catch (ClassNotFoundException | IllegalAccessException | InstantiationException |
NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
/**
* 是否是动态配置IP
*
* @param iface 网络接口
* @return boolean 结果
*/
public boolean isDynamic(String iface) {
try {
Object configuration = getConfigurationMethod.invoke(ethManager, iface);
@SuppressLint("PrivateApi")
Class> ipCnClz = Class.forName("android.net.IpConfiguration");
Log.d(TAG, "isDynamic: " + ipCnClz.getField("ipAssignment").get(configuration));
return ipCnClz.getField("ipAssignment").get(configuration).toString().equals("DHCP");
} catch (IllegalAccessException | InvocationTargetException | ClassNotFoundException |
NoSuchFieldException e) {
throw new RuntimeException(e);
}
}
/**
* 设置动态ip
*
* @param iface 接口名称
*/
public void setDynamicIp(String iface) {
try {
@SuppressLint("PrivateApi")
Class> ipCnClz = Class.forName("android.net.IpConfiguration");
Object ipConfiguration = ipCnClz.newInstance();
Map ipConfigurationEnum = getIpConfigurationEnum(ipCnClz);
Field ipAssignment = ipCnClz.getField("ipAssignment");
ipAssignment.set(ipConfiguration, ipConfigurationEnum.get("IpAssignment.DHCP"));
Field proxySettings = ipCnClz.getField("proxySettings");
proxySettings.set(ipConfiguration, ipConfigurationEnum.get("ProxySettings.NONE"));
setConfigurationMethod.invoke(ethManager, iface, ipConfiguration);
} catch (IllegalAccessException | InstantiationException | NoSuchFieldException |
ClassNotFoundException | InvocationTargetException e) {
Log.d(TAG, "setDynamicIp: " + e);
}
}
/**
* 设置静态ip
*
* @param iface 可用接口
* @param ipAddress ip地址
* @param netmask 子网掩码
* @param gateway 网关
* @param dns dns
*/
public void setStaticIp(String iface, String ipAddress, String netmask, String gateway, String dns) {
if (!isAvailable(iface)) {
return;
}
Object staticIpConfiguration = setStaticIpConfiguration(ipAddress, netmask, gateway, dns);
try {
Object ipConfiguration = newIpConfiguration(staticIpConfiguration);
setConfigurationMethod.invoke(ethManager, iface, ipConfiguration);
} catch (Exception e) {
// throw new RuntimeException(e);
Log.d(TAG, "setStaticIp: " + e);
}
}
/**
* 配置静态IP
* @param staticIpConfiguration 静态IP配置
*/
private Object newIpConfiguration(Object staticIpConfiguration) throws Exception {
@SuppressLint("PrivateApi") Class> ipConfigurationCls = Class.forName("android.net.IpConfiguration");
Object ipConfiguration = ipConfigurationCls.newInstance();
Field staticIpConfigurationField = ipConfigurationCls.getField("staticIpConfiguration");
staticIpConfigurationField.set(ipConfiguration, staticIpConfiguration);
Map ipConfigurationEnum = getIpConfigurationEnum(ipConfigurationCls);
Field ipAssignment = ipConfigurationCls.getField("ipAssignment");
ipAssignment.set(ipConfiguration, ipConfigurationEnum.get("IpAssignment.STATIC"));
Field proxySettings = ipConfigurationCls.getField("proxySettings");
proxySettings.set(ipConfiguration, ipConfigurationEnum.get("ProxySettings.STATIC"));
return ipConfiguration;
}
/**
* 设置静态ip配置
*
* @param address ip地址
* @param mask 子网掩码
* @param gate 门关
* @param dns dns
* @return {@link Object}
*/
public Object setStaticIpConfiguration(String address, String mask, String gate, String dns) {
try {
Log.d(TAG, "setStaticIpConfiguration: address = " + address + " netmask = " + mask + " gateway = " + gate + " dns = " + dns);
@SuppressLint("PrivateApi")
Class> staticIpConfigurationClz = Class.forName("android.net.StaticIpConfiguration");
Object staticIpConfiguration = staticIpConfigurationClz.newInstance();
Field ipAddress = staticIpConfigurationClz.getField("ipAddress");
Field netmask = staticIpConfigurationClz.getField("domains");
Field gateway = staticIpConfigurationClz.getField("gateway");
Field dnsServers = staticIpConfigurationClz.getField("dnsServers");
ipAddress.set(staticIpConfiguration, getLinkAddress(InetAddress.getByName(address), getPrefixLength(address)));
netmask.set(staticIpConfiguration, mask);
gateway.set(staticIpConfiguration, InetAddress.getByName(gate));
ArrayList dnsList = (ArrayList) dnsServers.get(staticIpConfiguration);
dnsList.add(InetAddress.getByName(dns));
return staticIpConfiguration;
} catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException |
InstantiationException | UnknownHostException e) {
Log.d(TAG, "setStaticIpConfiguration: " + e);
return null;
}
}
/**
* 得到链接地址
*
* @param address 地址
* @param length 长度
* @return {@link LinkAddress}
*/
public LinkAddress getLinkAddress(InetAddress address, int length) {
try {
Class> linkAddressClz = Class.forName("android.net.LinkAddress");
Constructor> linkAddressCsr = linkAddressClz.getConstructor(InetAddress.class, int.class);
return (LinkAddress) linkAddressCsr.newInstance(address, length);
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException |
InstantiationException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
/**
* 获取长度
*/
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;
}
/**
* 获得可用接口
*
* @return {@link String[]} 接口名称
*/
public String[] getAvailableInterfaces() {
try {
return (String[]) getAvailableInterfacesMethod.invoke(ethManager);
} catch (IllegalAccessException | InvocationTargetException e) {
Log.d(TAG, "getAvailableInterfaces: " + e);
return new String[]{};
}
}
/**
* 获取IpConfiguration的枚举值
*/
private static Map getIpConfigurationEnum(Class> ipConfigurationCls) {
Map 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;
}
/**
* 是否可用
*
* @param iface iface
* @return boolean
*/
public boolean isAvailable(String iface) {
try {
return (boolean) isAvailableMethod.invoke(ethManager, iface);
} catch (IllegalAccessException | InvocationTargetException e) {
Log.d(TAG, "isAvailable: " + e);
return false;
}
}
/**
* 获得ip地址
*
* @param iface iface
* @return {@link String}
*/
public String getIpAddress(String iface) {
try {
return (String) getIpAddressMethod.invoke(ethManager, iface);
} catch (IllegalAccessException | InvocationTargetException e) {
Log.d(TAG, "getIpAddress: " + e);
return "0.0.0.0";
}
}
/**
* 得到子网掩码
*
* @param iface iface
* @return {@link String}
*/
public String getNetmask(String iface) {
try {
return (String) getNetmaskMethod.invoke(ethManager, iface);
} catch (IllegalAccessException | InvocationTargetException e) {
Log.d(TAG, "getNetmask: " + e);
return "0.0.0.0";
}
}
/**
* 获得网关
*
* @param iface iface
* @return {@link String}
*/
public String getGateway(String iface) {
try {
return (String) getGatewayMethod.invoke(ethManager, iface);
} catch (IllegalAccessException | InvocationTargetException e) {
Log.d(TAG, "getGateway: " + e);
return "0.0.0.0";
}
}
/**
* 获得dns
*
* @param iface iface
* @return {@link String}
*/
public String getDns(String iface) {
try {
return ((String) getDnsMethod.invoke(ethManager, iface)).replace(",", "");
} catch (IllegalAccessException | InvocationTargetException e) {
Log.d(TAG, "getDns: " + e);
return "0.0.0.0";
}
}
/**
* ipv4正则表达式
*/
private static final Pattern IPV4_REGEX =
Pattern.compile(
"^(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}$");
/**
* 判断是否为合法IPv4地址
*
* @param input 输入
* @return boolean 判断结果
*/
public static boolean isIPv4Address(final String input) {
return IPV4_REGEX.matcher(input).matches();
}
}