问题
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);
回答1:
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)
{
}
}
回答2:
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);
回答3:
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());
}
}
来源:https://stackoverflow.com/questions/12486441/how-can-i-set-proxysettings-and-proxyproperties-on-android-wi-fi-connection-usin