2.X:
ContentResolver ctRes = mContext.getContentResolver();
Settings.System.putInt(ctRes,Settings.System.WIFI_USE_STATIC_IP, 1);
Settings.System.putString(ctRes,Settings.System.WIFI_STATIC_IP, "192.168.1.44");
3.X/4.X(亲测4.4可用):
public boolean setStaticIp(String setIp) {
WifiConfiguration wifiConfig = getConnectConfig();
if (wifiConfig==null){
return false;
}
try {
setIpAssignment("STATIC", wifiConfig);
setIpAddress(InetAddress.getByName(setIp), 24, wifiConfig);
int netId = mWifiManager.updateNetwork(wifiConfig);
boolean result = netId!= -1; //apply the setting
if(result){
boolean isDisconnected = mWifiManager.disconnect();
boolean configSaved = mWifiManager.saveConfiguration(); //Save it
boolean isEnabled = mWifiManager.enableNetwork(wifiConfig.networkId, true);
// reconnect with the new static IP
boolean isReconnected = mWifiManager.reconnect();
}
Log.i(TAG,"静态ip设置成功!");
return true;
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG,"静态ip设置失败!"+e.getLocalizedMessage());
return false;
}
}
public WifiConfiguration getConnectConfig(){
WifiInfo connectionInfo = getConnectionInfo();
List<WifiConfiguration> configuredNetworks = startScan2();
WifiConfiguration wifiConfig = null;
if (configuredNetworks != null) {
for (WifiConfiguration conf : configuredNetworks) {
if (conf.networkId == connectionInfo.getNetworkId()) {
wifiConfig = conf;
break;
}
}
}
return wifiConfig;
}
public WifiInfo getConnectionInfo() {
return mWifiManager.getConnectionInfo();
}
public List<WifiConfiguration> startScan2() {
mWifiManager.startScan();
// 得到扫描结果
// mWifiList = mWifiManager.getScanResults();
// 得到配置好的网络连接
mWifiConfigurations = mWifiManager.getConfiguredNetworks();
return mWifiConfigurations;
}
public static void setIpAssignment(String assign, WifiConfiguration wifiConf)
throws SecurityException, IllegalArgumentException,
NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Object ipConfiguration = wifiConf.getClass().getMethod("getIpConfiguration").invoke(wifiConf);
setEnumField(ipConfiguration, assign, "ipAssignment");
}
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<Enum>) f.getType(), value));
}
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<Object> mLinkAddresses = (ArrayList<Object>) getDeclaredField(
linkProperties, "mLinkAddresses");
mLinkAddresses.clear();
mLinkAddresses.add(linkAddress);
}
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;
}
5.X+(亲测7.0可用):
@SuppressWarnings("unchecked")
private 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<Enum> enumClz = (Class<Enum>)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> T getField(Object object, String fieldName, Class<T> 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);
}
调用:
try{
setStaticIpConfiguration(mWifiManager, wifiConfig,
InetAddress.getByName("192.168.1.44"), 24,
InetAddress.getByName("192.168.1.45"),
new InetAddress[] { InetAddress.getByName("192.168.1.46"), InetAddress.getByName("192.168.1.47") });
Log.e(TAG,"setStaticIpConfiguration成功 ");
}catch (Exception e){
e.printStackTrace();
Log.e(TAG,"setStaticIpConfiguration失败: "+e.toString());
}
测试7.0用4.X的方法的时候报错:
java.lang.NoSuchFieldException:ipAssignment
是因为ipAssignment
字段仍然出现在L预览中(至少是grepcode中的版本),但它不在发布的版本中:
试着通过反射方法修改,将setIpAssignment方法修改为:
Object ipConfiguration = wifiConf.getClass().getMethod("getIpConfiguration").invoke(wifiConf);
setEnumField(ipConfiguration, assign, "ipAssignment");
试了之后又报错:
java.lang.NoSuchFieldException: linkProperties
源代码已将linkProperties删除:https://github.com/aosp-mirror/platform_frameworks_base/commit/0a82e80073e193725a9d4c84a93db8a04b2456b9
最后根据源码新IpConfiguration
类现在拥有StaticIpConfiguration
这些字段,可以根据反射来修改.
Android 碎片化太严重,低版本和高版本之间代码修改很多,开发中碰到问题可以去查看相关源码,源码中注释及方法很清楚,问题总会解决的.