如何以编程方式configue一个静态IP地址,子网掩码,网关在Android 3.x或4.x版 [英] How to configue a static IP address, netmask, gateway programmatically on Android 3.x or 4.x

查看:1191
本文介绍了如何以编程方式configue一个静态IP地址,子网掩码,网关在Android 3.x或4.x版的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的堆栈溢出问题的 在Android应用程序配置静态IP地址 的API已经检查。

I have checked in Stack Overflow question API for configuring static IP addresses in an Android application.

它的工作原理到安卓2.3。然而,在一个更​​高的API级没有运气。例如, 我把设置

It works until Android 2.3. However, there is no luck on a higher API level. For example, I put the setting

android.provider.Settings.System.putString(getContentResolver(), android.provider.Settings.System.WIFI_USE_STATIC_IP, "1");        
android.provider.Settings.System.putString(getContentResolver(), android.provider.Settings.System.WIFI_STATIC_IP, "192.168.0.100");
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_DNS1, "192.168.0.254");
android.provider.Settings.System.putString(getContentResolver(), android.provider.Settings.System.WIFI_STATIC_GATEWAY, "192.168.0.254");

不过,我回去查方式:

But I go back to check by:

Setting --> Wi-Fi --> Long Press Access Point SSID --> Modify Network --> check Show advanced options

IP设置字段仍然指出 DHCP 而不是静态

The IP Settings field is still stated DHCP but not Static.

这是事实,我可以使用 android.provider.Settings.System.getString()来找回我的设置。它证明​​,设置的地方保存,但该系统只是忽略它。

It is true that I can use android.provider.Settings.System.getString() to get back what I set. It prove that the setting is saved somewhere but the system just ignore it.

本系统采用比 android.provider.Settings.System 的其他设置在Android 3.x和4.x的设置是每个接入点的SSID设置。我可以修改一个SSID设置,就像它是如何工作在Android 2.3?

The system uses the setting other than android.provider.Settings.System on Android 3.x and 4.x as the setting is set per Access Point SSID. Can I modify the setting on one SSID just like how it works on Android 2.3?

推荐答案

我认识到,没有对3.x或4.x的那些每个SSID设置的API。所以,我检查了源$ C ​​$ c和发现了一个SSID的配置存储在 android.net.wifi.WifiConfiguration ,从<$ C $得到C> android.net.wifi.WifiManager 。

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 one SSID is stored in android.net.wifi.WifiConfiguration, get from android.net.wifi.WifiManager.

其中, IpAssignment 是一个枚举,无论是 STAIC DHCP NONE 。 和 linkProperties 是对象存储的IP地址,网关,DNS等...

Where IpAssignment is an Enum, either STAIC, DHCP or NONE. and linkProperties is the object store IP address, gateway, DNS, etc...

linkAddress上是IP地址和为prefixLength(多少位1的网络掩码)。

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

mRoutes 的ArrayList RouteInfo ,可以指示网关。

mRoutes is ArrayList of RouteInfo that can indicate gateway.

mDnses 的ArrayList 的InetAddress 的DNS的。

首先,获得当前使用的SSID WifiConfiguration

Firstly, get the current using SSID WifiConfiguration

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 是隐藏的,该对象可以从反射得到。

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

下面的方法可以设置SSID WifiConfiguration申报的IP地址设置:

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

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

在这之后,我可以设置设置和更新 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 3.x的设备有silmilar UI与Android 4.x的 在安卓3.x中,网关storted linkProperties mGateways mGateways 的ArrayList 类型的InetAddress 。因此,下面应该在的Andr​​oid 3.X。

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:该方法 setIpAddress setGateway setDNS 应输入为的InetAddress 键入

这篇关于如何以编程方式configue一个静态IP地址,子网掩码,网关在Android 3.x或4.x版的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆