如何设置以太网有线网络静态配置
从源码看设置以太网配置调用的是EthernetManager的setConfiguration方法,
所以我们就只需要创建IpConfiguration这个实例,他的构造方法传入值是
最终配置的参数就是StaticIpConfiguration这个类来配置ipAddress,gateway,dnsServers这三个值
涉及的类主要有,但这些都是隐藏的apk无法调用,只能通过反射进行调用,但前提是你的apk是系统apk,不然没有权限。
private static final String ClassName_EthernetManager = "android.net.EthernetManager";
private static final String ClassName_StaticIpConfiguration = "android.net.StaticIpConfiguration";
private static final String ClassName_IpConfiguration = "android.net.IpConfiguration";
private static final String ClassName_IpAssignment = "android.net.IpConfiguration$IpAssignment";
private static final String ClassName_ProxySettings = "android.net.IpConfiguration$ProxySettings";
private static final String ClassName_ProxyInfo = "android.net.ProxyInfo";
通过反射设置以太网静态配置的值
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.Method;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
import com.das.function.reflection.ReflectionFunctions;
public class EthernetFunctions extends ReflectionFunctions{
private static final String ClassName_EthernetManager = "android.net.EthernetManager";
private static final String ClassName_StaticIpConfiguration = "android.net.StaticIpConfiguration";
private static final String ClassName_IpConfiguration = "android.net.IpConfiguration";
private static final String ClassName_IpAssignment = "android.net.IpConfiguration$IpAssignment";
private static final String ClassName_ProxySettings = "android.net.IpConfiguration$ProxySettings";
private static final String ClassName_ProxyInfo = "android.net.ProxyInfo";
EthernetFunctions(Context context) {
super(context);
//设置信息
}
public void updateEthDevInfo(boolean dhcp, String ip, String gatewayConfig, String subnetmask, String[] dns) {
//获取EthernetManager
try {
final Class<?> classEthernetManager = getClass(ClassName_EthernetManager);//获取EthernetManager
Object IEthernetManager = getSystemServiceInstance("ethernet");//获取EthernetManager实例
Method MSetEthEnabled = getMethod(classEthernetManager, "isAvailable");
//获取StaticIpConfiguration
final Class<?> classStaticIpConfiguration = getClass(ClassName_StaticIpConfiguration);
Object IStaticIpConfiguration = getNewInstance(classStaticIpConfiguration);
Field ipAddress = getField(classStaticIpConfiguration, "ipAddress"); //获取ipAddress
Field gateway = getField(classStaticIpConfiguration, "gateway"); //获取gateway
Field dnsServers = getField(classStaticIpConfiguration, "dnsServers"); //获取dnsServers
Class clazz = null;
clazz = Class.forName("android.net.LinkAddress");
Class[] cl = new Class[]{InetAddress.class, int.class};
Constructor cons = null;
cons = clazz.getConstructor(cl);
InetAddress ipAddressValue = InetAddress.getByName("192.168.249.5");
Object[] x = {ipAddressValue, 16};
setField(IStaticIpConfiguration, ipAddress, (LinkAddress) cons.newInstance(x)); //ipAddress赋值
InetAddress gatewayValue = InetAddress.getByName("192.168.249.2");
setField(IStaticIpConfiguration, gateway, gatewayValue); //gateway赋值
InetAddress dnsServersValue1 = InetAddress.getByName("192.168.249.3"); //dns1
InetAddress dnsServersValue2 = InetAddress.getByName("192.168.249.4"); //dns2
List<InetAddress> dnsValues = new ArrayList<>();
dnsValues.add(dnsServersValue1);
dnsValues.add(dnsServersValue2);
setField(IStaticIpConfiguration, dnsServers, dnsValues); //dnsServers赋值
Method MToString = getMethod(classStaticIpConfiguration, "toString");
Log.i("MSetIfName", "EthernetFunctions: " + MToString.invoke(IStaticIpConfiguration));
//获取IpConfiguration
final Class<?> classIpConfiguration = getClass(ClassName_IpConfiguration);
final Class<?> classIpAssignment = getClass(ClassName_IpAssignment);
final Class<?> classProxySettings = getClass(ClassName_ProxySettings);
final Class<?> classProxyInfo = getClass(ClassName_ProxyInfo);
Object[] assignments = classIpAssignment.getEnumConstants(); //获取枚举值
Object[] proxySettings = classProxySettings.getEnumConstants(); //获取枚举值
Constructor constructor = classIpConfiguration.getConstructor(classIpAssignment, classProxySettings, classStaticIpConfiguration, classProxyInfo);
Object IIpConfiguration = constructor.newInstance(assignments[0], proxySettings[1], IStaticIpConfiguration, null);
Method MSetConfiguration = getMethod(classEthernetManager, "setConfiguration",classIpConfiguration);
invokeMethod(MSetConfiguration, IEthernetManager, IIpConfiguration);//设置值
} catch (Exception e) {
e.printStackTrace();
}
}
}
反射工具类
import android.content.Context;
import android.util.Log;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectionFunctions {
public static Process ExecRuntimeCommand(String command) {
try {
return Runtime.getRuntime().exec(command);
} catch (IOException e) {
Log.e("execRuntimeCommand", e.getMessage());
}
return null;
}
public static Process ExecRuntimeSUCommand(String command) {
try {
return Runtime.getRuntime().exec(new String[]{"su", "-c", command});
} catch (IOException e) {
Log.e("execRuntimeCommand", e.getMessage());
}
return null;
}
private Context context;
public static Boolean TRUE = Boolean.TRUE;
public static Boolean FALSE = Boolean.FALSE;
public static Class<?> BOOLEAN = Boolean.TYPE;
public static Class<?> CHAR = char.class;
public static Class<?> INT = int.class;
public static Class<?> SHORT = short.class;
public static Class<?> LONG = long.class;
public static Class<?> FLOAT = float.class;
public static Class<?> DOUBLE = double.class;
public static Class<?> BYTE = byte.class;
public static Class<?> STRING = String.class;
public ReflectionFunctions(Context context) {
this.context = context;
}
public Context getContext() {
return context;
}
protected Process execRuntimeCommand(String command) {
return ReflectionFunctions.ExecRuntimeCommand(command);
}
protected Process execRuntimeSUCommand(String command) {
return ReflectionFunctions.ExecRuntimeSUCommand(command);
}
protected Class<?> getClass(String className) throws ClassNotFoundException {
return Class.forName(className);
}
protected Object getNewInstance(Class<?> classType) throws IllegalAccessException, InstantiationException {
return classType.newInstance();
}
protected Object getSystemServiceInstance(String name) {
return getContext().getSystemService(name);
}
protected Method getMethod(String className, String methodName, Class<?>... params) throws ClassNotFoundException, NoSuchMethodException {
return getMethod(getClass(className), methodName, params);
}
protected Method getMethod(Class<?> classType, String methodName, Class<?>... params) throws NoSuchMethodException {
return classType.getMethod(methodName, params);
}
protected Field getField(Class<?> classType,String fieldName) throws NoSuchFieldException {
return classType.getField(fieldName);
}
protected void setField(Object classInstance,Field field,Object value) throws NoSuchFieldException, IllegalAccessException {
field.setAccessible(true);
field.set(classInstance,value);
}
protected Object invokeMethod(Method method, Object classInstance, Object... methodParams) throws InvocationTargetException, IllegalAccessException {
try {
return method.invoke(classInstance, methodParams);
} catch (SecurityException e) {
new ReflectionException("", e).printStackTrace();
method.setAccessible(true);
return invokeMethod(method, classInstance, methodParams);
}
}
private static class ReflectionException extends RuntimeException {
private ReflectionException(String message, Exception exception) {
super(message, exception);
}
}
附主要类源码
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net;
import android.content.Context;
import android.net.IEthernetManager;
import android.net.IEthernetServiceListener;
import android.net.IpConfiguration;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import java.util.ArrayList;
/**
* A class representing the IP configuration of the Ethernet network.
*
* @hide
*/
public class EthernetManager {
private static final String TAG = "EthernetManager";
private static final int MSG_AVAILABILITY_CHANGED = 1000;
private final Context mContext;
private final IEthernetManager mService;
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == MSG_AVAILABILITY_CHANGED) {
boolean isAvailable = (msg.arg1 == 1);
for (Listener listener : mListeners) {
listener.onAvailabilityChanged(isAvailable);
}
}
}
};
private final ArrayList<Listener> mListeners = new ArrayList<Listener>();
private final IEthernetServiceListener.Stub mServiceListener =
new IEthernetServiceListener.Stub() {
@Override
public void onAvailabilityChanged(boolean isAvailable) {
mHandler.obtainMessage(
MSG_AVAILABILITY_CHANGED, isAvailable ? 1 : 0, 0, null).sendToTarget();
}
};
/**
* A listener interface to receive notification on changes in Ethernet.
*/
public interface Listener {
/**
* Called when Ethernet port's availability is changed.
* @param isAvailable {@code true} if one or more Ethernet port exists.
*/
public void onAvailabilityChanged(boolean isAvailable);
}
/**
* Create a new EthernetManager instance.
* Applications will almost always want to use
* {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
* the standard {@link android.content.Context#ETHERNET_SERVICE Context.ETHERNET_SERVICE}.
*/
public EthernetManager(Context context, IEthernetManager service) {
mContext = context;
mService = service;
}
/**
* Get Ethernet configuration.
* @return the Ethernet Configuration, contained in {@link IpConfiguration}.
*/
public IpConfiguration getConfiguration() {
try {
return mService.getConfiguration();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Set Ethernet configuration.
*/
public void setConfiguration(IpConfiguration config) {
try {
mService.setConfiguration(config);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Indicates whether the system currently has one or more
* Ethernet interfaces.
*/
public boolean isAvailable() {
try {
return mService.isAvailable();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Adds a listener.
* @param listener A {@link Listener} to add.
* @throws IllegalArgumentException If the listener is null.
*/
public void addListener(Listener listener) {
if (listener == null) {
throw new IllegalArgumentException("listener must not be null");
}
mListeners.add(listener);
if (mListeners.size() == 1) {
try {
mService.addListener(mServiceListener);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
/**
* Removes a listener.
* @param listener A {@link Listener} to remove.
* @throws IllegalArgumentException If the listener is null.
*/
public void removeListener(Listener listener) {
if (listener == null) {
throw new IllegalArgumentException("listener must not be null");
}
mListeners.remove(listener);
if (mListeners.isEmpty()) {
try {
mService.removeListener(mServiceListener);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
}
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net;
import android.net.StaticIpConfiguration;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.Objects;
/**
* A class representing a configured network.
* @hide
*/
public class IpConfiguration implements Parcelable {
private static final String TAG = "IpConfiguration";
public enum IpAssignment {
/* Use statically configured IP settings. Configuration can be accessed
* with staticIpConfiguration */
STATIC,
/* Use dynamically configured IP settigns */
DHCP,
/* no IP details are assigned, this is used to indicate
* that any existing IP settings should be retained */
UNASSIGNED
}
public IpAssignment ipAssignment;
public StaticIpConfiguration staticIpConfiguration;
public enum ProxySettings {
/* No proxy is to be used. Any existing proxy settings
* should be cleared. */
NONE,
/* Use statically configured proxy. Configuration can be accessed
* with httpProxy. */
STATIC,
/* no proxy details are assigned, this is used to indicate
* that any existing proxy settings should be retained */
UNASSIGNED,
/* Use a Pac based proxy.
*/
PAC
}
public ProxySettings proxySettings;
public ProxyInfo httpProxy;
private void init(IpAssignment ipAssignment,
ProxySettings proxySettings,
StaticIpConfiguration staticIpConfiguration,
ProxyInfo httpProxy) {
this.ipAssignment = ipAssignment;
this.proxySettings = proxySettings;
this.staticIpConfiguration = (staticIpConfiguration == null) ?
null : new StaticIpConfiguration(staticIpConfiguration);
this.httpProxy = (httpProxy == null) ?
null : new ProxyInfo(httpProxy);
}
public IpConfiguration() {
init(IpAssignment.UNASSIGNED, ProxySettings.UNASSIGNED, null, null);
}
public IpConfiguration(IpAssignment ipAssignment,
ProxySettings proxySettings,
StaticIpConfiguration staticIpConfiguration,
ProxyInfo httpProxy) {
init(ipAssignment, proxySettings, staticIpConfiguration, httpProxy);
}
public IpConfiguration(IpConfiguration source) {
this();
if (source != null) {
init(source.ipAssignment, source.proxySettings,
source.staticIpConfiguration, source.httpProxy);
}
}
public IpAssignment getIpAssignment() {
return ipAssignment;
}
public void setIpAssignment(IpAssignment ipAssignment) {
this.ipAssignment = ipAssignment;
}
public StaticIpConfiguration getStaticIpConfiguration() {
return staticIpConfiguration;
}
public void setStaticIpConfiguration(StaticIpConfiguration staticIpConfiguration) {
this.staticIpConfiguration = staticIpConfiguration;
}
public ProxySettings getProxySettings() {
return proxySettings;
}
public void setProxySettings(ProxySettings proxySettings) {
this.proxySettings = proxySettings;
}
public ProxyInfo getHttpProxy() {
return httpProxy;
}
public void setHttpProxy(ProxyInfo httpProxy) {
this.httpProxy = httpProxy;
}
@Override
public String toString() {
StringBuilder sbuf = new StringBuilder();
sbuf.append("IP assignment: " + ipAssignment.toString());
sbuf.append("\n");
if (staticIpConfiguration != null) {
sbuf.append("Static configuration: " + staticIpConfiguration.toString());
sbuf.append("\n");
}
sbuf.append("Proxy settings: " + proxySettings.toString());
sbuf.append("\n");
if (httpProxy != null) {
sbuf.append("HTTP proxy: " + httpProxy.toString());
sbuf.append("\n");
}
return sbuf.toString();
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof IpConfiguration)) {
return false;
}
IpConfiguration other = (IpConfiguration) o;
return this.ipAssignment == other.ipAssignment &&
this.proxySettings == other.proxySettings &&
Objects.equals(this.staticIpConfiguration, other.staticIpConfiguration) &&
Objects.equals(this.httpProxy, other.httpProxy);
}
@Override
public int hashCode() {
return 13 + (staticIpConfiguration != null ? staticIpConfiguration.hashCode() : 0) +
17 * ipAssignment.ordinal() +
47 * proxySettings.ordinal() +
83 * httpProxy.hashCode();
}
/** Implement the Parcelable interface */
public int describeContents() {
return 0;
}
/** Implement the Parcelable interface */
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(ipAssignment.name());
dest.writeString(proxySettings.name());
dest.writeParcelable(staticIpConfiguration, flags);
dest.writeParcelable(httpProxy, flags);
}
/** Implement the Parcelable interface */
public static final Creator<IpConfiguration> CREATOR =
new Creator<IpConfiguration>() {
public IpConfiguration createFromParcel(Parcel in) {
IpConfiguration config = new IpConfiguration();
config.ipAssignment = IpAssignment.valueOf(in.readString());
config.proxySettings = ProxySettings.valueOf(in.readString());
config.staticIpConfiguration = in.readParcelable(null);
config.httpProxy = in.readParcelable(null);
return config;
}
public IpConfiguration[] newArray(int size) {
return new IpConfiguration[size];
}
};
}
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net;
import android.net.LinkAddress;
import android.os.Parcelable;
import android.os.Parcel;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* Class that describes static IP configuration.
*
* This class is different from LinkProperties because it represents
* configuration intent. The general contract is that if we can represent
* a configuration here, then we should be able to configure it on a network.
* The intent is that it closely match the UI we have for configuring networks.
*
* In contrast, LinkProperties represents current state. It is much more
* expressive. For example, it supports multiple IP addresses, multiple routes,
* stacked interfaces, and so on. Because LinkProperties is so expressive,
* using it to represent configuration intent as well as current state causes
* problems. For example, we could unknowingly save a configuration that we are
* not in fact capable of applying, or we could save a configuration that the
* UI cannot display, which has the potential for malicious code to hide
* hostile or unexpected configuration from the user: see, for example,
* http://b/12663469 and http://b/16893413 .
*
* @hide
*/
public class StaticIpConfiguration implements Parcelable {
public LinkAddress ipAddress;
public InetAddress gateway;
public final ArrayList<InetAddress> dnsServers;
public String domains;
public StaticIpConfiguration() {
dnsServers = new ArrayList<InetAddress>();
}
public StaticIpConfiguration(StaticIpConfiguration source) {
this();
if (source != null) {
// All of these except dnsServers are immutable, so no need to make copies.
ipAddress = source.ipAddress;
gateway = source.gateway;
dnsServers.addAll(source.dnsServers);
domains = source.domains;
}
}
public void clear() {
ipAddress = null;
gateway = null;
dnsServers.clear();
domains = null;
}
/**
* Returns the network routes specified by this object. Will typically include a
* directly-connected route for the IP address's local subnet and a default route. If the
* default gateway is not covered by the directly-connected route, it will also contain a host
* route to the gateway as well. This configuration is arguably invalid, but it used to work
* in K and earlier, and other OSes appear to accept it.
*/
public List<RouteInfo> getRoutes(String iface) {
List<RouteInfo> routes = new ArrayList<RouteInfo>(3);
if (ipAddress != null) {
RouteInfo connectedRoute = new RouteInfo(ipAddress, null, iface);
routes.add(connectedRoute);
if (gateway != null && !connectedRoute.matches(gateway)) {
routes.add(RouteInfo.makeHostRoute(gateway, iface));
}
}
if (gateway != null) {
routes.add(new RouteInfo((IpPrefix) null, gateway, iface));
}
return routes;
}
/**
* Returns a LinkProperties object expressing the data in this object. Note that the information
* contained in the LinkProperties will not be a complete picture of the link's configuration,
* because any configuration information that is obtained dynamically by the network (e.g.,
* IPv6 configuration) will not be included.
*/
public LinkProperties toLinkProperties(String iface) {
LinkProperties lp = new LinkProperties();
lp.setInterfaceName(iface);
if (ipAddress != null) {
lp.addLinkAddress(ipAddress);
}
for (RouteInfo route : getRoutes(iface)) {
lp.addRoute(route);
}
for (InetAddress dns : dnsServers) {
lp.addDnsServer(dns);
}
lp.setDomains(domains);
return lp;
}
public String toString() {
StringBuffer str = new StringBuffer();
str.append("IP address ");
if (ipAddress != null ) str.append(ipAddress).append(" ");
str.append("Gateway ");
if (gateway != null) str.append(gateway.getHostAddress()).append(" ");
str.append(" DNS servers: [");
for (InetAddress dnsServer : dnsServers) {
str.append(" ").append(dnsServer.getHostAddress());
}
str.append(" ] Domains ");
if (domains != null) str.append(domains);
return str.toString();
}
public int hashCode() {
int result = 13;
result = 47 * result + (ipAddress == null ? 0 : ipAddress.hashCode());
result = 47 * result + (gateway == null ? 0 : gateway.hashCode());
result = 47 * result + (domains == null ? 0 : domains.hashCode());
result = 47 * result + dnsServers.hashCode();
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof StaticIpConfiguration)) return false;
StaticIpConfiguration other = (StaticIpConfiguration) obj;
return other != null &&
Objects.equals(ipAddress, other.ipAddress) &&
Objects.equals(gateway, other.gateway) &&
dnsServers.equals(other.dnsServers) &&
Objects.equals(domains, other.domains);
}
/** Implement the Parcelable interface */
public static Creator<StaticIpConfiguration> CREATOR =
new Creator<StaticIpConfiguration>() {
public StaticIpConfiguration createFromParcel(Parcel in) {
StaticIpConfiguration s = new StaticIpConfiguration();
readFromParcel(s, in);
return s;
}
public StaticIpConfiguration[] newArray(int size) {
return new StaticIpConfiguration[size];
}
};
/** Implement the Parcelable interface */
public int describeContents() {
return 0;
}
/** Implement the Parcelable interface */
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(ipAddress, flags);
NetworkUtils.parcelInetAddress(dest, gateway, flags);
dest.writeInt(dnsServers.size());
for (InetAddress dnsServer : dnsServers) {
NetworkUtils.parcelInetAddress(dest, dnsServer, flags);
}
dest.writeString(domains);
}
protected static void readFromParcel(StaticIpConfiguration s, Parcel in) {
s.ipAddress = in.readParcelable(null);
s.gateway = NetworkUtils.unparcelInetAddress(in);
s.dnsServers.clear();
int size = in.readInt();
for (int i = 0; i < size; i++) {
s.dnsServers.add(NetworkUtils.unparcelInetAddress(in));
}
s.domains = in.readString();
}
}