Getting WiFi proxy settings in Android

2019-01-17 01:44发布

问题:

I am trying to read WIFI proxy settings

  • Proxy host
  • Proxy port
  • Proxy user (authentication)
  • Proxy password (authentication)

from devices in android versions 2.X.X – 4.X.X without any success.

Calling:

String proxy = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.HTTP_PROXY);

Always returns null.

I've also added to my android manifest:

<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />

still it returns null.

Also tried:

android.net.Proxy. getHost(Context ctx) – which is deprecated – returns the IP
android.net.Proxy. getPortt(Context ctx) – which is deprecated – returns always -1.

Java calls:

System.getProperty("http.proxyHost");
System.getProperty("http.proxyCall");

Also returns null.

Is there a working code which retrieves all these settings or at least partially from devices in all android versions?

回答1:

I found this project: Android Proxy Library Which provides backward compatible ways of querying Proxy settings as well as setting them for WebViews on older versions of Android.

    // Grab Proxy settings in a backwards compatible manner
    ProxyConfiguration proxyConfig = ProxySettings.getCurrentHttpProxyConfiguration( context );

    // Set Proxy for WebViews on older versions of Android
    ProxyUtils.setWebViewProxy( getActivity().getApplicationContext() );

However, there is something you need to understand about Proxy Settings set on a WiFi AP. Since WiFi specific Proxy Settings were not implemented in Android proper until 3.1, all pre-3.1 devices that expose that functionality are using some sort of custom hack. They don't work in any sort of standard way. So libraries like this won't be able to grab any proxy set from one of those hacks.

There is however a System Wide Proxy in pre-3.1 that this sort of library WILL grab. Of course Android saw fit not to provide any official way to modify this setting. But there are apps on the Play Store that will allow you to do it, this is the one I'm using: Proxy Settings and it works well, setting the System Proxy and allowing you to grab it either via this library, or even simpler methods like querying the JVM proxy settings.

I ended up not using the APL and instead went with a much simpler implementation:

    private static final boolean IS_ICS_OR_LATER = Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;

    ...

    String proxyAddress;
    int proxyPort;

    if( IS_ICS_OR_LATER )
    {
        proxyAddress = System.getProperty( "http.proxyHost" );

        String portStr = System.getProperty( "http.proxyPort" );
        proxyPort = Integer.parseInt( ( portStr != null ? portStr : "-1" ) );
    }
    else
    {
        proxyAddress = android.net.Proxy.getHost( context );
        proxyPort = android.net.Proxy.getPort( context );
    }


回答2:

This is what I'm using:

public static String[] getUserProxy(Context context)
{
    Method method = null;
    try
    {
      method = ConnectivityManager.class.getMethod("getProxy");
    }
    catch (NoSuchMethodException e)
    {
      // Normal situation for pre-ICS devices
      return null;
    }
    catch (Exception e)
    {
      return null;
    }

    try
    {
      ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
      Object pp = method.invoke(connectivityManager);
      if (pp == null)
        return null;

      return getUserProxy(pp);
    }
    catch (Exception e)
    {
      return null;
    }
  }


private static String[] getUserProxy(Object pp) throws Exception
{
    String[] userProxy = new String[3];

    String className = "android.net.ProxyProperties";
    Class<?> c = Class.forName(className);
    Method method;

    method = c.getMethod("getHost");
    userProxy[0] = (String) method.invoke(pp);

    method = c.getMethod("getPort");
    userProxy[1] = String.valueOf((Integer) method.invoke(pp));


    method = c.getMethod("getExclusionList");
    userProxy[2] = (String) method.invoke(pp);

    if (userProxy[0] != null)
      return userProxy;
    else
      return null;
}


回答3:

Following is code snippet to retrieve proxy details

public static String getProxyDetails(Context context) {
        String proxyAddress = new String();
        try {
            if (IsPreIcs()) {
                proxyAddress = android.net.Proxy.getHost(context);
                if (proxyAddress == null || proxyAddress.equals("")) {
                    return proxyAddress;
                }
                proxyAddress += ":" + android.net.Proxy.getPort(context);
            } else {
                proxyAddress = System.getProperty("http.proxyHost");
                proxyAddress += ":" + System.getProperty("http.proxyPort");
            }
        } catch (Exception ex) {
            //ignore
        }
        return proxyAddress;
    }

It'll return enmpty if some exception or no proxy detected;