Android 修改静态IP地址

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中的版本),但它不在发布的版本中:

源代码:https://android.googlesource.com/platform/frameworks/base/+/master/wifi/java/android/net/wifi/WifiConfiguration.java

试着通过反射方法修改,将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 碎片化太严重,低版本和高版本之间代码修改很多,开发中碰到问题可以去查看相关源码,源码中注释及方法很清楚,问题总会解决的.

 

参考:https://stackoverflow.com/questions/27599564/how-to-configure-a-static-ip-address-netmask-gateway-dns-programmatically-on/27671207#27671207

 

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值