How can I set ProxySettings and ProxyProperties on Android Wi-Fi connection using Java?
Asked Answered
T

3

11

How can I set ProxySettings and ProxyProperties on an Android Wi-Fi connection using Java (programatically)?

As ipAssignment, linkProperties, ProxySettings and ProxyProperties are hidden fields within WifiConfiguration on Android 3.1 and up, I need to be able to enum the class and use the fields.

Following the code sample using the link below, I can set a static IP address, gateway and DNS for a particular Wi-Fi connection, but I also need to set Wificonfiguration.ProxySettings.STATIC and ProxyProperties

See Stack Overflow question How to configue a static IP address, netmask, gateway programmatically on Android 3.x or 4.x.

For example,

WifiConfiguration config = new WifiConfiguration(configuration);
config.ipAssignment = WifiConfiguration.IpAssignment.UNASSIGNED;
config.proxySettings = WifiConfiguration.ProxySettings.STATIC;
config.linkProperties.setHttpProxy(new ProxyProperties("127.0.0.1", 3128, ""));

Looking for something like:

setProxySettings("STATIC", wifiConf);
setProxyProperties("proxyserver.mine.com.au", 8080, ""); // Set Proxy server and port.
wifiManager.updateNetwork(wifiConf); //apply the setting

Using the following code from coolypf .ipAssignment .ProxySettings and linkProperties are hidden...

    WifiManager manager = (WifiManager)getSystemService(Context.WIFI_SERVICE);
manager.asyncConnect(this, new Handler());
if (!manager.isWifiEnabled()) return;
    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;
    }
    if (configuration == null) return;
    WifiConfiguration config = new WifiConfiguration(configuration);
    config.ipAssignment = WifiConfiguration.IpAssignment.UNASSIGNED;
    config.proxySettings = WifiConfiguration.ProxySettings.STATIC;

    config.linkProperties.clear();

    config.linkProperties.setHttpProxy(new ProxyProperties("127.0.0.1", 3128, ""));

    manager.saveNetwork(config);
Tracay answered 18/9, 2012 at 23:17 Comment(0)
B
15

Here's some code that should allow you to set/unset ProxyProperties. It uses some of the same code from the link above. The settings do not seem to take effect with the disconnect/reconnect.

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()
{
    //get the current wifi configuration
    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);

        //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] = null;

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

        //save the settings
        manager.updateNetwork(config);
        manager.disconnect();
        manager.reconnect();
    }   
    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)
    {
    }
}
Brozak answered 12/1, 2013 at 15:25 Comment(7)
what do you mean with "The settings do not seem to take effect with the disconnect/reconnect." ?Stasiastasis
This is not working on Android 2.3.6 . Error : "No such field exception " Line : Object linkProperties = getField(config, "linkProperties"); in setWifiProxySettings()Freemon
@carl i dont hv static option in proxy for my hp tablet 4.4 version there is only 2 option NONE and Manual can plz suggest how to do for manual?Paoting
do you know if programmatically I can know if a wifi has services blockeds like whatsapp instagram, etc..?Paraphrastic
I had to add manager.saveConfiguration(); as well and in addition, the manager.reconnect(); connected to another configured WiFi - so take care ... ;)Ustulation
Hi Carl I get an error "No such field exception " Line : Object linkProperties = getField(config, "linkProperties"). Could you please send me a sample code . Thank you very much .Summation
The code attempts to call the setHttpProxy method on the linkPropertiesField object, which is of type Field. This does not work, since the Field class does not have this method. Instead, the method must be called on the LinkProperties object which is the value of this field. Get the field's value from the config object and call the method on that. The line has to look like this: setHttpProxy.invoke(linkProperties.get(config), params);Zama
C
7

Similar to Dave's answer, but fewer lines by using only the method setProxy(ProxySettings settings, ProxyInfo proxy) (surrounding code omitted for clarity):

Class proxySettings = Class.forName("android.net.IpConfiguration$ProxySettings");

Class[] setProxyParams = new Class[2];
setProxyParams[0] = proxySettings;
setProxyParams[1] = ProxyInfo.class;

Method setProxy = config.getClass().getDeclaredMethod("setProxy", setProxyParams);
setProxy.setAccessible(true);

ProxyInfo desiredProxy = ProxyInfo.buildDirectProxy(YOUR_HOST, YOUR_PORT);

Object[] methodParams = new Object[2];
methodParams[0] = Enum.valueOf(proxySettings, "STATIC");
methodParams[1] = desiredProxy;

setProxy.invoke(config, methodParams);
Conaway answered 27/11, 2015 at 2:4 Comment(3)
This code works well but not in Android 8. E/WifiConfigManager: UID 10610 does not have permission to modify proxy Settings. What is workaround?Becky
Android 8 added a public API to set the proxy, but restricts it to device owners and profile owners: developer.android.com/reference/android/net/wifi/…. There does not appear to be a workaround.Zama
How can I set wifi configurations in android 29 API?Haematoxylon
T
5

Here is some sample code to handle the same thing in Android 5.0 following the same format as Carl's answer above.

public void setWifiProxySettings5()
{
    //get the current wifi configuration
    WifiManager manager = (WifiManager)getSystemService(Context.WIFI_SERVICE);
    WifiConfiguration config = GetCurrentWifiConfiguration(manager);
    if(null == config)
        return;     

    try
    {       
        //linkProperties is no longer in WifiConfiguration          
        Class proxyInfoClass = Class.forName("android.net.ProxyInfo");
        Class[] setHttpProxyParams = new Class[1];
        setHttpProxyParams[0] = proxyInfoClass;         
        Class wifiConfigClass = Class.forName("android.net.wifi.WifiConfiguration");
        Method setHttpProxy = wifiConfigClass.getDeclaredMethod("setHttpProxy", setHttpProxyParams);
        setHttpProxy.setAccessible(true);

        //Method 1 to get the ENUM ProxySettings in IpConfiguration
        Class ipConfigClass = Class.forName("android.net.IpConfiguration");
        Field f = ipConfigClass.getField("proxySettings");
        Class proxySettingsClass = f.getType();        

        //Method 2 to get the ENUM ProxySettings in IpConfiguration
        //Note the $ between the class and ENUM
        //Class proxySettingsClass = Class.forName("android.net.IpConfiguration$ProxySettings");

        Class[] setProxySettingsParams = new Class[1];
        setProxySettingsParams[0] = proxySettingsClass;
        Method setProxySettings = wifiConfigClass.getDeclaredMethod("setProxySettings", setProxySettingsParams);
        setProxySettings.setAccessible(true);


        ProxyInfo pi = ProxyInfo.buildDirectProxy("127.0.0.1", 8118);
        //Android 5 supports a PAC file
        //ENUM value is "PAC"
        //ProxyInfo pacInfo = ProxyInfo.buildPacProxy(Uri.parse("http://localhost/pac"));

        //pass the new object to setHttpProxy
        Object[] params_SetHttpProxy = new Object[1];
        params_SetHttpProxy[0] = pi;
        setHttpProxy.invoke(config, params_SetHttpProxy);

        //pass the enum to setProxySettings
        Object[] params_setProxySettings = new Object[1];
        params_setProxySettings[0] = Enum.valueOf((Class<Enum>) proxySettingsClass, "STATIC");
        setProxySettings.invoke(config, params_setProxySettings);

        //save the settings
        manager.updateNetwork(config);
        manager.disconnect();
        manager.reconnect();
    }   
    catch(Exception e)
    {
        Log.v("wifiProxy", e.toString());
    }
}
Tele answered 13/2, 2015 at 19:36 Comment(1)
For Android 6 this code also works, BUT unfortunately you cannot update a network that you have not created yourself. This is because of the new Android Wifi rules: developer.android.com/about/versions/marshmallow/…Aluminize

© 2022 - 2024 — McMap. All rights reserved.