changed wifi advanced option from code but it won't work?

柔情痞子 提交于 2020-01-13 07:00:28

问题


I used this code to change wifi Ip setting (Ip Address and gateway)

you can see the full code here : full class

WifiConfiguration wifiConf = null;
    WifiManager manager = (WifiManager) getSystemService(MainActivity.WIFI_SERVICE);
        WifiInfo connectionInfo = manager.getConnectionInfo();
    List<WifiConfiguration> configuredNetworks = manager
            .getConfiguredNetworks();

    wifiConf = GetCurrentWifiConfiguration(manager);

setIpAssignment("STATIC", wifiConf); 
setIpAddress(InetAddress.getByName("192.2.2.2"), 24, wifiConf);
setGateway(InetAddress.getByName("192.2.2.22"), wifiConf);
manager.updateNetwork(wifiConf); 
manager.saveConfiguration(); 

functions:

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

problem is here :

these codes successfully change the ip address and gateway when you check wifi connection advanced option from setting in your android device, but the setting actually isn't set!!!

how I understand this :

first I set a fake Ip address and gateway manually, modify network-> advanced option. and then try to open a website with chrome, no internet access and it worked. then I set the same Ip address and gateway for connected ssid from code but It's not worked and still have internet access.

I used same settings from code and manually but its not worked from code. where I did wrong ?


回答1:


As I see this you were able to change the settings and get the values changed on settings view, but the actual change on system state on device did not happen.

You most propably don't have privileges to change wifi settings with your program.

Try adding the following:

ACCESS_WIFI_STATE
CHANGE_WIFI_STATE
ACCESS_NETWORK_STATE

See my comments on question for more information.




回答2:


Adding any number of duplicate SSID's is possible if you have a unique IP address.

In lay man's terms SSID is nothing but just an identification given to that particular network given to distinguish that network from others for simplicity. What defines that network is it's IP Address.If you have a conflict between an IP address then it may be a real problem.

For some devices(like Samsung) you need to check the to Display open Network connection if available in order to view open connections and for some devices it shows by default.

Ex:-Let's say you have two network's with SSID as Test. Test1 has an open connection available for public use and Test2 is for personal use and is encrypted. Your mobile device will simply connect to a network whose signal strength is good. As the IP address is different there will not be any conflict and you can do your browsing.

In case there's any conflict(same signal strength) then the device will ask the user to select the desired network or search for a new network.

Caution:-Browsing an open network for reasons related to finance leads to severe security threats browse at your own risk.

An IP address serves two principal functions: host or network interface identification and location addressing. Its role has been characterized as follows: "A name indicates what we seek. An address indicates where it is. A route indicates how to get there.

The most simple definition for IP Address I could give is-

IP address act as you house address to which the shipment has to be delivered.If you have two same addresses then to whom will the shipment be delivered. For further details about IP read this

Now basically my answer to your question is :

You can defiantly add multiple setting with ssid but different security level

SMALL DEMO I HAVE PREPARED :

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        connectToAP("12345", "12345");

        WifiConfiguration wifiConf = null;
        WifiManager wifiManager = (WifiManager) getSystemService(MainActivity.WIFI_SERVICE);
        WifiInfo connectionInfo = wifiManager.getConnectionInfo();
        List<WifiConfiguration> configuredNetworks = wifiManager
                .getConfiguredNetworks();
        for (WifiConfiguration conf : configuredNetworks) {
            if (conf.networkId == 9) {

                wifiConf = conf;
                setWifiProxySettings(wifiConf);

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

    }

    public static void setIpAssignment(String assign, WifiConfiguration wifiConf)
            throws SecurityException, IllegalArgumentException,
            NoSuchFieldException, IllegalAccessException {
        setEnumField(wifiConf, 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 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;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    String TAG = "wifi";
    WifiManager wifiManager;

    public void connectToAP(String ssid, String passkey) {
        Log.i(TAG, "* connectToAP");
        wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
        WifiConfiguration wifiConfiguration = new WifiConfiguration();

        String networkSSID = ssid;
        String networkPass = passkey;

        Log.d(TAG, "# password " + networkPass);

        // for (ScanResult result : scanResultList) {
        // if (result.SSID.equals(networkSSID)) {
        if (true) {
            // String securityMode = getScanResultSecurity(result);
            String securityMode = "OPEN";
            if (securityMode.equalsIgnoreCase("OPEN")) {

                wifiConfiguration.SSID = "\"" + networkSSID + "\"";
                wifiConfiguration.allowedKeyManagement
                        .set(WifiConfiguration.KeyMgmt.NONE);
                int res = wifiManager.addNetwork(wifiConfiguration);
                Log.d(TAG, "# add Network returned " + res);

                boolean b = wifiManager.enableNetwork(res, true);
                Log.d(TAG, "# enableNetwork returned " + b);

                wifiManager.setWifiEnabled(true);

            } else if (securityMode.equalsIgnoreCase("WEP")) {

                wifiConfiguration.SSID = "\"" + networkSSID + "\"";
                wifiConfiguration.wepKeys[0] = "\"" + networkPass + "\"";
                wifiConfiguration.wepTxKeyIndex = 0;
                wifiConfiguration.allowedKeyManagement
                        .set(WifiConfiguration.KeyMgmt.NONE);
                wifiConfiguration.allowedGroupCiphers
                        .set(WifiConfiguration.GroupCipher.WEP40);
                int res = wifiManager.addNetwork(wifiConfiguration);
                Log.d(TAG, "### 1 ### add Network returned " + res);

                boolean b = wifiManager.enableNetwork(res, true);
                Log.d(TAG, "# enableNetwork returned " + b);

                wifiManager.setWifiEnabled(true);
            }

            wifiConfiguration.SSID = "\"" + networkSSID + "\"";
            wifiConfiguration.preSharedKey = "\"" + networkPass + "\"";
            wifiConfiguration.hiddenSSID = true;
            wifiConfiguration.status = WifiConfiguration.Status.ENABLED;
            wifiConfiguration.allowedGroupCiphers
                    .set(WifiConfiguration.GroupCipher.TKIP);
            wifiConfiguration.allowedGroupCiphers
                    .set(WifiConfiguration.GroupCipher.CCMP);
            wifiConfiguration.allowedKeyManagement
                    .set(WifiConfiguration.KeyMgmt.WPA_PSK);
            wifiConfiguration.allowedPairwiseCiphers
                    .set(WifiConfiguration.PairwiseCipher.TKIP);
            wifiConfiguration.allowedPairwiseCiphers
                    .set(WifiConfiguration.PairwiseCipher.CCMP);
            wifiConfiguration.allowedProtocols
                    .set(WifiConfiguration.Protocol.RSN);
            wifiConfiguration.allowedProtocols
                    .set(WifiConfiguration.Protocol.WPA);

            int res = wifiManager.addNetwork(wifiConfiguration);
            Log.d(TAG, "### 2 ### add Network returned " + res);

            wifiManager.enableNetwork(res, true);

            boolean changeHappen = wifiManager.saveConfiguration();

            if (res != -1 && changeHappen) {
                Log.d(TAG, "### Change happen");

                // AppStaticVar.connectedSsidName = networkSSID;

            } else {
                Log.d(TAG, "*** Change NOT happen");
            }

            wifiManager.setWifiEnabled(true);
        }
        // }
    }

    public String getScanResultSecurity(ScanResult scanResult) {
        Log.i(TAG, "* getScanResultSecurity");

        final String cap = scanResult.capabilities;
        final String[] securityModes = { "WEP", "PSK", "EAP" };

        for (int i = securityModes.length - 1; i >= 0; i--) {
            if (cap.contains(securityModes[i])) {
                return securityModes[i];
            }
        }

        return "OPEN";
    }

    /* PROXY SETTINGS */
    /*********************************************************************/
    // 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));
    // }

    public static void setProxySettings(String assign,
            WifiConfiguration wifiConf) throws SecurityException,
            IllegalArgumentException, NoSuchFieldException,
            IllegalAccessException {
        setEnumField(wifiConf, assign, "proxySettings");
    }

    WifiConfiguration GetCurrentWifiConfiguration(WifiManager manager) {
        if (!manager.isWifiEnabled())
            return null;

        List<WifiConfiguration> configurationList = manager
                .getConfiguredNetworks();
        WifiConfiguration configuration = null;
        int cur = manager.getConnectionInfo().getNetworkId();
        for (int i = 0; i < configurationList.size(); ++i) {
            WifiConfiguration wifiConfiguration = configurationList.get(i);
            if (wifiConfiguration.networkId == cur)
                configuration = wifiConfiguration;
        }

        return configuration;
    }

    void setWifiProxySettings(WifiConfiguration config) {

        if (null == config)
            return;

        try {

            Object linkProperties = getField(config, "linkProperties");
            if (null == linkProperties)
                return;

            Class proxyPropertiesClass = Class
                    .forName("android.net.ProxyProperties");
            Class[] setHttpProxyParams = new Class[1];
            setHttpProxyParams[0] = proxyPropertiesClass;
            Class lpClass = Class.forName("android.net.LinkProperties");
            Method setHttpProxy = lpClass.getDeclaredMethod("setHttpProxy",
                    setHttpProxyParams);
            setHttpProxy.setAccessible(true);

            // get ProxyProperties constructor
            Class[] proxyPropertiesCtorParamTypes = new Class[3];
            proxyPropertiesCtorParamTypes[0] = String.class;
            proxyPropertiesCtorParamTypes[1] = int.class;
            proxyPropertiesCtorParamTypes[2] = String.class;

            Constructor proxyPropertiesCtor = proxyPropertiesClass
                    .getConstructor(proxyPropertiesCtorParamTypes);

            // create the parameters for the constructor
            Object[] proxyPropertiesCtorParams = new Object[3];
            proxyPropertiesCtorParams[0] = "127.0.0.1";
            proxyPropertiesCtorParams[1] = 8118;
            proxyPropertiesCtorParams[2] = "example.com";

            // create a new object using the params
            Object proxySettings = proxyPropertiesCtor
                    .newInstance(proxyPropertiesCtorParams);

            // pass the new object to setHttpProxy
            Object[] params = new Object[1];
            params[0] = proxySettings;
            setHttpProxy.invoke(linkProperties, params);

            setProxySettings("STATIC", config);

        } catch (Exception e) {
        }
    }

    void unsetWifiProxySettings() {
        WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
        WifiConfiguration config = GetCurrentWifiConfiguration(manager);
        if (null == config)
            return;

        try {
            // get the link properties from the wifi configuration
            Object linkProperties = getField(config, "linkProperties");
            if (null == linkProperties)
                return;

            // get the setHttpProxy method for LinkProperties
            Class proxyPropertiesClass = Class
                    .forName("android.net.ProxyProperties");
            Class[] setHttpProxyParams = new Class[1];
            setHttpProxyParams[0] = proxyPropertiesClass;
            Class lpClass = Class.forName("android.net.LinkProperties");
            Method setHttpProxy = lpClass.getDeclaredMethod("setHttpProxy",
                    setHttpProxyParams);
            setHttpProxy.setAccessible(true);

            // pass null as the proxy
            Object[] params = new Object[1];
            params[0] = null;
            setHttpProxy.invoke(linkProperties, params);

            setProxySettings("NONE", config);

            // save the config
            manager.updateNetwork(config);
            manager.disconnect();
            manager.reconnect();
        } catch (Exception e) {
        }
    }

}

HERE IN ABOVE CODE TRY RUNNING SAME CODE WITH :

  String securityMode = "OPEN";

  String securityMode = "WEP";

once at a time :

OBSERVATION :BOTH THE SETTINGS GET ADDED PROGRAMMATICALLY BUT CAN BE SEEN ONLY ONCE SINCE BOTH ARE OVERLAPPING WITH EACH OTHER..BUT BOTH ARE PRESENT. now question is how do I know both is present? 1. Run above code. 2. once with OPEN as security level and once with WEP 3. once added tab the wifi and there is option of forgot network..click it 4. You will observer that although you deleted it, it's still there :) 5. Hence both the settings are there but get overlapped programmatically.

MY ANALYSIS WITH HOTSPOT :

I turned 2 device as hotspot with same ssid but different security level and i can see 2 separate wifi but the thing is when added programmatically it stay there but overlapping.

NOTE : ADDING MANUALLY OR PROGRAMMATICALLY SAME WIFI SETTING WILL SURLY OVERWRITE EXISTING ONE BUT EVEN WITH 1 SETTING DIFFERENCE IT WORKS.




回答3:


mWifiManager.updateNetwork(selectWIfiConfi);
mWifiManager.saveConfiguration();
mWifiManager.setWifiEnabled(false);

mWifiManager.setWifiEnabled(true);

I reopen wifi and it works phone`s version 4.2.2



来源:https://stackoverflow.com/questions/25303151/changed-wifi-advanced-option-from-code-but-it-wont-work

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!