Search code examples
androidandroid-wifiwifimanagerwifi

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


Can anybody tell me how can I set the static IP and gateway programmatically in Android 6?

I have read here and here.

Settings.System is not working anymore and goolgle says WIFI_STATIC_IP was deprecated in API level 17 and Use WifiManger instead. Unfortunately I cannot find anything about it in WifiManger and WifiConfigurationclasses.


Solution

  • 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" />