我意识到在3.x或4.x上没有针对每个SSID的那些设置的API。因此,我检查了源代码,发现每个SSID的配置都存储在
android.net.wifi.WifiConfiguration其中,该配置是从中获取的
android.net.wifi.WifiManager。
在下面的代码,
IpAssignment是一个枚举,无论是
STAIC,
DHCP或
NONE。并且
linkProperties是对象存储的IP地址,网关,DNS等。
linkAddress是IP地址,其网络掩码为
prefixLength(网络掩码中的多少位1)。
mRoutes是
ArrayList的
RouteInfo,可以指示网关。
mDnses是
ArrayList的
InetAddress对DNS。
首先,使用WifiConfigurationSSID 获取当前配置
WifiConfiguration wifiConf = null;WifiManager wifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);WifiInfo connectionInfo = wifiManager.getConnectionInfo();List<WifiConfiguration> configuredNetworks = wifiManager.getConfiguredNetworks(); for (WifiConfiguration conf : configuredNetworks){ if (conf.networkId == connectionInfo.getNetworkId()){ wifiConf = conf; break; }}由于IpAssignment和linkProperties被隐藏,因此可以从反射中获取对象。
以下方法可以在SSID WifiConfiguration上设置声明的IP地址设置:
public static void setIpAssignment(String assign , WifiConfiguration wifiConf) throws SecurityException, IllegalArgumentException, NoSuchFieldException, IllegalAccessException{ setEnumField(wifiConf, assign, "ipAssignment"); } 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{ Object linkProperties = getField(wifiConf, "linkProperties"); if(linkProperties == null)return; ArrayList<InetAddress> mDnses = (ArrayList<InetAddress>)getDeclaredField(linkProperties, "mDnses"); 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; } private 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)); }之后,我可以WifiConfiguration为此SSID进行设置和更新。
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(); }编辑:对不起,我没有检查具有Android 4.x的silmilar UI的Android 3.x设备。在Android 3.x中,网关存储在
mGateways中
linkProperties。
mGateways是
Arraylist类型
InetAddress。因此,以下操作应在Android 3.x中起作用。
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); }EDIT2:所述方法setIpAddress,setGateway,setDNS应当被输入作为InetAddress类型。



