NoSuchFieldExecption:ipAssignment
android里设置静态Ip在android6.0的系统中出现NoSuchFieldExecption:ipAssignment的异常。原来在5.0+的版本后ipAssignment属性设置改成setIpAssignment的方法调用。
3.0+ 和 4.0+ 基本都一样
public static void setIpAssignment(String assign, WifiConfiguration wifiConf)
throws SecurityException, IllegalArgumentException,
NoSuchFieldException, IllegalAccessException,
InvocationTargetException, NoSuchMethodException {
if (Build.VERSION.SDK_INT >= 21) {
Object ipConfiguration = wifiConf.getClass()
.getMethod("getIpConfiguration").invoke(wifiConf);
setEnumField(ipConfiguration, assign, "ipAssignment");
} else {
setEnumField(wifiConf, assign, "ipAssignment");
}
}
@SuppressWarnings("unchecked")
public static void setIpAddress(InetAddress addr, int prefixLength,
WifiConfiguration wifiConf) throws SecurityException,
IllegalArgumentException, NoSuchFieldException,
IllegalAccessException, NoSuchMethodException,
ClassNotFoundException, InstantiationException,
InvocationTargetException {
Object linkProperties = getField(wifiConf, "linkProperties");
if (linkProperties == null)
return;
Class laClass = Class.forName("android.net.LinkAddress");
Constructor laConstructor = laClass.getConstructor(new Class[] {
InetAddress.class, int.class });
Object linkAddress = laConstructor.newInstance(addr, prefixLength);
ArrayList mLinkAddresses = (ArrayList) getDeclaredField(linkProperties,
"mLinkAddresses");
mLinkAddresses.clear();
mLinkAddresses.add(linkAddress);
}
public static void setGateway(InetAddress gateway,
WifiConfiguration wifiConf) throws SecurityException,
IllegalArgumentException, NoSuchFieldException,
IllegalAccessException, ClassNotFoundException,
NoSuchMethodException, InstantiationException,
InvocationTargetException {
Object linkProperties = getField(wifiConf, "linkProperties");
if (linkProperties == null)
return;
Class routeInfoClass = Class.forName("android.net.RouteInfo");
Constructor routeInfoConstructor = routeInfoClass
.getConstructor(new Class[] { InetAddress.class });
Object routeInfo = routeInfoConstructor.newInstance(gateway);
ArrayList mRoutes = (ArrayList) getDeclaredField(linkProperties,
"mRoutes");
mRoutes.clear();
mRoutes.add(routeInfo);
}
public static void setDNS(InetAddress dns, WifiConfiguration wifiConf)
throws SecurityException, IllegalArgumentException,
NoSuchFieldException, IllegalAccessException,
InvocationTargetException, NoSuchMethodException {
Object linkProperties = null;
ArrayList mDnses = null;
if (Build.VERSION.SDK_INT >= 21) {
Object staticIpConf = wifiConf.getClass()
.getMethod("getStaticIpConfiguration").invoke(wifiConf);
mDnses = (ArrayList) getDeclaredField(staticIpConf,
"dnsServers");
} else {
linkProperties = getField(wifiConf, "linkProperties");
mDnses = (ArrayList) getDeclaredField(linkProperties,
"mDnses");
}
if (linkProperties == null)
return;
mDnses.clear(); // or add a new dns address , here I just want to
// replace DNS1
mDnses.add(dns);
}
public static Object getField(Object obj, String name)
throws SecurityException, NoSuchFieldException,
IllegalArgumentException, IllegalAccessException {
Field f = obj.getClass().getField(name);
Object out = f.get(obj);
return out;
}
public static Object getDeclaredField(Object obj, String name)
throws SecurityException, NoSuchFieldException,
IllegalArgumentException, IllegalAccessException {
Field f = obj.getClass().getDeclaredField(name);
f.setAccessible(true);
Object out = f.get(obj);
return out;
}
public static void setEnumField(Object obj, String value, String name)
throws SecurityException, NoSuchFieldException,
IllegalArgumentException, IllegalAccessException {
Field f = obj.getClass().getField(name);
f.set(obj, Enum.valueOf((Class) f.getType(), value));
}
//使用方式:
try{
setIpAssignment(“STATIC”, wifiConf); //or “DHCP” for dynamic setting
setIpAddress(InetAddress.getByName(“192.168.0.100”), 24, wifiConf);
setGateway(InetAddress.getByName(“4.4.4.4”), wifiConf);
setDNS(InetAddress.getByName(“4.4.4.4”), wifiConf);
wifiManager.updateNetwork(wifiConf); //apply the setting
wifiManager.saveConfiguration(); //Save it
}catch(Exception e){
e.printStackTrace();
}
//3.0差别:
public static void setGateway(InetAddress gateway, WifiConfiguration wifiConf)
throws SecurityException, IllegalArgumentException, NoSuchFieldException, IllegalAccessException,
ClassNotFoundException, NoSuchMethodException, InstantiationException, InvocationTargetException{
Object linkProperties = getField(wifiConf, "linkProperties");
if(linkProperties == null)return;
ArrayList mGateways = (ArrayList)getDeclaredField(linkProperties, "mGateways");
mGateways.clear();
mGateways.add(gateway);
}
Android L即5.0+使用方法
public static void setStaticIpConfiguration(WifiManager manager,
WifiConfiguration config, InetAddress ipAddress, int prefixLength,
InetAddress gateway, InetAddress[] dns)
throws ClassNotFoundException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException,
NoSuchMethodException, NoSuchFieldException, InstantiationException {
// First set up IpAssignment to STATIC.
Object ipAssignment = getEnumValue(
"android.net.IpConfiguration$IpAssignment", "STATIC");
callMethod(config, "setIpAssignment",
new String[] { "android.net.IpConfiguration$IpAssignment" },
new Object[] { ipAssignment });
// Then set properties in StaticIpConfiguration.
Object staticIpConfig = newInstance("android.net.StaticIpConfiguration");
Object linkAddress = newInstance("android.net.LinkAddress",
new Class[] { InetAddress.class, int.class }, new Object[] {
ipAddress, prefixLength });
setField(staticIpConfig, "ipAddress", linkAddress);
setField(staticIpConfig, "gateway", gateway);
getField(staticIpConfig, "dnsServers", ArrayList.class).clear();
for (int i = 0; i < dns.length; i++)
getField(staticIpConfig, "dnsServers", ArrayList.class).add(dns[i]);
callMethod(config, "setStaticIpConfiguration",
new String[] { "android.net.StaticIpConfiguration" },
new Object[] { staticIpConfig });
manager.updateNetwork(config);
manager.saveConfiguration();
}
private static Object newInstance(String className)
throws ClassNotFoundException, InstantiationException,
IllegalAccessException, NoSuchMethodException,
IllegalArgumentException, InvocationTargetException {
return newInstance(className, new Class[0], new Object[0]);
}
private static Object newInstance(String className,
Class[] parameterClasses, Object[] parameterValues)
throws NoSuchMethodException, InstantiationException,
IllegalAccessException, IllegalArgumentException,
InvocationTargetException, ClassNotFoundException {
Class clz = Class.forName(className);
Constructor constructor = clz.getConstructor(parameterClasses);
return constructor.newInstance(parameterValues);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private static Object getEnumValue(String enumClassName, String enumValue)
throws ClassNotFoundException {
Class enumClz = (Class) Class.forName(enumClassName);
return Enum.valueOf(enumClz, enumValue);
}
private static void setField(Object object, String fieldName, Object value)
throws IllegalAccessException, IllegalArgumentException,
NoSuchFieldException {
Field field = object.getClass().getDeclaredField(fieldName);
field.set(object, value);
}
private static T getField(Object object, String fieldName, Class type)
throws IllegalAccessException, IllegalArgumentException,
NoSuchFieldException {
Field field = object.getClass().getDeclaredField(fieldName);
return type.cast(field.get(object));
}
private static void callMethod(Object object, String methodName,
String[] parameterTypes, Object[] parameterValues)
throws ClassNotFoundException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException,
NoSuchMethodException {
Class[] parameterClasses = new Class[parameterTypes.length];
for (int i = 0; i < parameterTypes.length; i++)
parameterClasses[i] = Class.forName(parameterTypes[i]);
Method method = object.getClass().getDeclaredMethod(methodName,
parameterClasses);
method.invoke(object, parameterValues);
}
//直接使用set方法调用 可能遇到需要地址转换方法如下:
public static String int2ip(int ip) {
StringBuilder sb = new StringBuilder();
sb.append(String.valueOf((int) (ip & 0xff)));
sb.append('.');
sb.append(String.valueOf((int) ((ip >> 8) & 0xff)));
sb.append('.');
sb.append(String.valueOf((int) ((ip >> 16) & 0xff)));
sb.append('.');
sb.append(String.valueOf((int) ((ip >> 24) & 0xff)));
return sb.toString();
}
参考文章:Android设置WIFI静态IP
您可能也对下面文章感兴趣:
There are 1 Comments to "NoSuchFieldExecption:ipAssignment"