Set Android Ip,Dns,Gateway Setting Programmatically

Set Android IP,DNS,GATEWAY setting programmatically

You can change system settings programatically.

First you need to request the 'WRITE_SETTINGS' permission in your 'AndroidManifest.xml':

<uses-permission android:name="android.permission.WRITE_SETTINGS"/>

Then you need to actually change the setting using the following code:

    android.provider.Settings.System.putString(getContentResolver(), android.provider.Settings.System.WIFI_USE_STATIC_IP, "0");
android.provider.Settings.System.putString(getContentResolver(), android.provider.Settings.System.WIFI_STATIC_DNS1, "192.168.0.2");
android.provider.Settings.System.putString(getContentResolver(), android.provider.Settings.System.WIFI_STATIC_DNS2, "192.168.0.3");
android.provider.Settings.System.putString(getContentResolver(), android.provider.Settings.System.WIFI_STATIC_GATEWAY, "192.168.0.1");
android.provider.Settings.System.putString(getContentResolver(), android.provider.Settings.System.WIFI_STATIC_NETMASK, "255.255.255.0");
android.provider.Settings.System.putString(getContentResolver(), android.provider.Settings.System.WIFI_STATIC_IP, "1");

The current settings can be accessed via the same method but use 'getString' instead of 'putString'.

For information about the settings option visit the reference here:
Settings.System | Android Developers

How to configure a static IP address, netmask, gateway, DNS programmatically on Android 5.x (Lollipop) for Wi-Fi connection

There is still no open API, unfortunately.

The solution for Android 4.0 doesn't work in LOLLIPOP because things have been moved around. In particular the new IpConfiguration class now holds the StaticIpConfiguration and all these fields. They can still be accessed by using reflection (with all the brittleness that entails) with something like this.

Warning, this code is Android 5.0-only. You'll need to check Build.VERSION.SDK_INT and act accordingly.

@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();
}

With the following helper methods to handle reflection:

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);
}

For example, you can call it like this:

public void test(Context context)
{
WifiManager manager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
WifiConfiguration wifiConf = ... /* Get Wifi configuration you want to update */

if (wifiConf != null)
{
try
{
setStaticIpConfiguration(manager, wifiConf,
InetAddress.getByName("10.0.0.1"), 24,
InetAddress.getByName("10.0.0.2"),
new InetAddress[] { InetAddress.getByName("10.0.0.3"), InetAddress.getByName("10.0.0.4") });
}
catch (Exception e)
{
e.printStackTrace();
}
}
}

As a reference, you might want to take a look at the WifiConfigController class in the framework (though it uses these classes directly instead of via reflection).

Set static IP and gateway programmatically in Android 6.x (Marshmallow)

Since there's no official API I have to come up with a solution by modifying samples from the following code snipet and this answer. This solution works on devices from Lollipop upwards.

 @SuppressWarnings("unchecked")
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});

int netId = manager.updateNetwork(config);
boolean result = netId != -1;
if (result) {
boolean isDisconnected = manager.disconnect();
boolean configSaved = manager.saveConfiguration();
boolean isEnabled = manager.enableNetwork(config.networkId, true);
boolean isReconnected = manager.reconnect();
}
}

Helper functions,

    public static WifiConfiguration getCurrentWiFiConfiguration(Context context) {
WifiConfiguration wifiConf = null;
ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (networkInfo.isConnected()) {
final WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
final WifiInfo connectionInfo = wifiManager.getConnectionInfo();
if (connectionInfo != null && !TextUtils.isEmpty(connectionInfo.getSSID())) {
List<WifiConfiguration> configuredNetworks = wifiManager.getConfiguredNetworks();
if (configuredNetworks != null) {
for (WifiConfiguration conf : configuredNetworks) {
if (conf.networkId == connectionInfo.getNetworkId()) {
wifiConf = conf;
break;
}
}
}
}
}
return wifiConf;
}

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);
}

To use it,

WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
WifiConfiguration wifiConf = WifiHelper.getCurrentWiFiConfiguration(getApplicationContext());

try {
setStaticIpConfiguration(wifiManager, wifiConf,
InetAddress.getByName("192.168.0.100"),
24,
InetAddress.getByName("10.0.0.2"),
new InetAddress[]{InetAddress.getByName("10.0.0.3"), InetAddress.getByName("10.0.0.4")});

} catch (Exception e) {
e.printStackTrace();
}

Finally you need to add those permissions in the manifest,

  <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />

How to configure a static IP address, netmask, gateway programmatically on Android 3.x or 4.x

I realise that there is no API on 3.x or 4.x for those setting per SSID. Therefore, I checked out the source code and found out that the configuration of each SSID is stored in android.net.wifi.WifiConfiguration which is gotten from android.net.wifi.WifiManager.

In the below code, IpAssignment is an Enum, either STAIC, DHCP or NONE.
And linkProperties is the object store IP address, gateway, DNS, etc...

linkAddress is IP address and its netmask as prefixLength (how many bit 1 in netmask).

mRoutes is ArrayList of RouteInfo that can indicate gateway.

mDnses is ArrayList of InetAddress for DNS.

Firstly, get the current configuration using WifiConfiguration SSID

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;
}
}

As the IpAssignment and linkProperties are hidden, the object can be gotten from reflection.

The following method can set the declared IP address setting on SSID WifiConfiguration:

    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));
}

After that, I can set setting and update WifiConfiguration for this 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();
}

Edit:
Sorry for I don't check for Android 3.x device that have silmilar UI with Android 4.x.
In Android 3.x, the gateway is storted in mGateways of linkProperties.
mGateways is Arraylist of type InetAddress. Therefore, following should work in 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: The methods setIpAddress, setGateway, setDNS should be inputted as InetAddress type.



Related Topics



Leave a reply



Submit