Android中的手动代理通过反射

时间:2014-07-11 12:17:49

标签: android proxy

我正在尝试通过反射在android中设置ssid,proxy,ipsetting,并且我通过反射在android中成功进行ssid和简短的ip设置,我的问题是我想通过反射以编程方式设置代理设置并且大部分代码都表示 STATIC和NONE 选项的实现,但是我的代理选项 NONE和MANUAL 的设备是否相同?下面是我的代理的代码plz建议我应该更改为手动代理实现的工作:

public static void setWifiProxySettings(WifiConfiguration config,
            WifiSetting wifiSetting) {
        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);

            Class[] proxyPropertiesCtorParamTypes = new Class[3];
            proxyPropertiesCtorParamTypes[0] = String.class;
            proxyPropertiesCtorParamTypes[1] = int.class;
            proxyPropertiesCtorParamTypes[2] = String.class;

            Constructor proxyPropertiesCtor = proxyPropertiesClass
                    .getConstructor(proxyPropertiesCtorParamTypes);

            Object[] proxyPropertiesCtorParams = new Object[3];
            URL proxyUrl = new URL(wifiSetting.getProxyHostName());

            proxyPropertiesCtorParams[0] = proxyUrl.getHost();
            proxyPropertiesCtorParams[1] = proxyUrl.getPort();
            proxyPropertiesCtorParams[2] = null;

            Object proxySettings = proxyPropertiesCtor
                    .newInstance(proxyPropertiesCtorParams);

            Object[] params = new Object[1];
            params[0] = proxySettings;
            setHttpProxy.invoke(linkProperties, params);

            setProxySettings("STATIC", config);

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

1 个答案:

答案 0 :(得分:3)

我通过反思在android下面写了apis for proxy:

  /**
         * This api is used for setting IP And Proxy Setting using below
         * supporting methods
         * 
         * @param wifiSetting
         * @param wifiConf
         */
        public static void setWifiSettings(WifiSetting wifiSetting,
                WifiConfiguration wifiConf) {
            // check if ip setting is static for custom ip setting
            // configration
            if ("STATIC".equals(wifiSetting.getIpSetting())) {
                setIpSettings(wifiSetting, wifiConf);
            }
            // if proxy is enabled set its custom proxy settings
            if (wifiSetting.getIsProxyEnabled() == true) {
                setWifiProxySettings(wifiSetting, wifiConf);
            }
        }

        /**
         * This api is used for setting IP
         * 
         * @param wifiSetting
         * @param wifiConf
         */
        private static void setIpSettings(WifiSetting wifiSetting,
                WifiConfiguration wifiConf) {
            try {
                setEnumField(wifiConf, "STATIC", "ipAssignment");
                setIpAddress(wifiSetting.getIpAddress(),
                        wifiSetting.getNetworkPrefixLength(), wifiConf);
                setGateway(wifiSetting.getGateway(), wifiConf);
                setDNS(wifiSetting, wifiConf);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        /**
         * This api is used for setting IpAddress in wifi settings
         * 
         * @param ipAddres
         * @param prefixLength
         */
        private static void setIpAddress(String ipAddress,
                int networkPrefixLength, WifiConfiguration wifiConf)
                throws SecurityException, IllegalArgumentException,
                NoSuchFieldException, IllegalAccessException,
                NoSuchMethodException, ClassNotFoundException,
                InstantiationException, InvocationTargetException {
            try {
                if (TextUtils.isEmpty(ipAddress)) {
                    throw new IllegalArgumentException(
                            "Required argument can not be blank.");
                }
                InetAddress inetAddr = null;
                Class networkUtils = Class.forName("android.net.NetworkUtils");
                Method numericToInetAddress = networkUtils.getDeclaredMethod(
                        "numericToInetAddress", ipAddress.getClass());
                inetAddr = (InetAddress) numericToInetAddress.invoke(null,
                        ipAddress);
                if (networkPrefixLength < 0 || networkPrefixLength > 32) {
                    throw new IllegalArgumentException(
                            "invalid networkPrefixLength parameter");
                }
                Object linkProperties = getFieldValue(wifiConf.getClass(),
                        wifiConf, "linkProperties");
                if (linkProperties == null) {
                    throw new IllegalArgumentException(
                            "Required argument can not be blank.");
                }
                Class<?> laClass = Class.forName("android.net.LinkAddress");
                Constructor<?> laConstructor = laClass
                        .getConstructor(new Class[] { InetAddress.class,
                                int.class });
                Object linkAddress = laConstructor.newInstance(inetAddr,
                        networkPrefixLength);
                Class<?> setIpAddress = Class
                        .forName("android.net.LinkProperties");
                Boolean result = (Boolean) invokeDeclaredMethod(setIpAddress,
                        linkProperties, "addLinkAddress",
                        new Class[] { laClass }, new Object[] { linkAddress });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        /**
         * This api is used for setting gateway in wifiConfigration
         * 
         * @param gateway
         * @param wifiConf
         */
        private static void setGateway(String gateway,
                WifiConfiguration wifiConf) throws SecurityException,
                IllegalArgumentException, NoSuchFieldException,
                IllegalAccessException, ClassNotFoundException,
                NoSuchMethodException, InstantiationException,
                InvocationTargetException {
            try {
                if (TextUtils.isEmpty(gateway)) {
                    throw new IllegalArgumentException(
                            "Required argument can not be blank.");
                }
                InetAddress inetAddr = null;
                Class networkUtils = Class.forName("android.net.NetworkUtils");
                Method numericToInetAddress = networkUtils.getDeclaredMethod(
                        "numericToInetAddress", gateway.getClass());
                inetAddr = (InetAddress) numericToInetAddress.invoke(null,
                        gateway);
                Object linkProperties = getFieldValue(wifiConf.getClass(),
                        wifiConf, "linkProperties");
                if (linkProperties == null) {
                    throw new IllegalArgumentException(
                            "Required argument can not be blank.");
                }
                Class routeInfoClass = Class.forName("android.net.RouteInfo");
                Constructor routeInfoConstructor = routeInfoClass
                        .getConstructor(new Class[] { InetAddress.class });
                Object routeInfo = routeInfoConstructor.newInstance(inetAddr);
                Class<?> linkPropertiesClass = Class
                        .forName("android.net.LinkProperties");
                Boolean result = (Boolean) invokeDeclaredMethod(
                        linkPropertiesClass, linkProperties, "addRoute",
                        new Class[] { routeInfoClass },
                        new Object[] { routeInfo });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        /**
         * This api is used for setting DNS in wifiConfigration
         * 
         * @param dns
         * @param wifiConf
         * @throws NoSuchMethodException
         * @throws InvocationTargetException
         */
        private static void setDNS(WifiSetting wifiSettings,
                WifiConfiguration wifiConf) throws SecurityException,
                IllegalArgumentException, NoSuchFieldException,
                IllegalAccessException, NoSuchMethodException,
                InvocationTargetException {
            try {
                String dns1 = wifiSettings.getDns1();
                String dns2 = wifiSettings.getDns2();
                if (TextUtils.isEmpty(dns1) && TextUtils.isEmpty(dns2)) {
                    throw new IllegalArgumentException(
                            "Required argument can not be blank.");
                }
                Class dnsInfo = Class.forName("android.net.NetworkUtils");
                Method setHttpProxy = dnsInfo.getDeclaredMethod(
                        "numericToInetAddress", String.class);
                InetAddress inetAddressDns1 = (InetAddress) setHttpProxy
                        .invoke(null, dns1);
                InetAddress inetAddressDns2 = (InetAddress) setHttpProxy
                        .invoke(null, dns2);
                Object linkProperties = getFieldValue(wifiConf.getClass(),
                        wifiConf, "linkProperties");
                if (linkProperties == null) {
                    throw new IllegalArgumentException(
                            "Required argument can not be blank.");
                }
                Class<?> linkPropertiesClass = Class
                        .forName("android.net.LinkProperties");
                Class<?> inetAddressClass = Class
                        .forName("java.net.InetAddress");
                invokeDeclaredMethod(linkPropertiesClass, linkProperties,
                        "addDns", new Class[] { inetAddressClass },
                        new Object[] { inetAddressDns1 });
                invokeDeclaredMethod(linkPropertiesClass, linkProperties,
                        "addDns", new Class[] { inetAddressClass },
                        new Object[] { inetAddressDns2 });
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (RemoteException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        /**
         * This api is used for setting Proxy in wifiConfigration
         * 
         * @param proxyHostName
         * @param proxyPort
         * @param proxyExceptions
         * @param config
         */
        private static void setWifiProxySettings(WifiSetting wifiSettings,
                WifiConfiguration config) {
            try {
                if (null == config) {
                    throw new IllegalArgumentException(
                            "Required argument can not be blank.");
                }
                // get the link properties from the wifi configuration
                Object linkProperties = getFieldValue(config.getClass(),
                        config, "linkProperties");
                if (null == linkProperties) {
                    throw new IllegalArgumentException(
                            "Required argument can not be blank.");
                }
                // 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] = wifiSettings.getProxyHostName();
                proxyPropertiesCtorParams[1] = wifiSettings.getProxyPort();
                proxyPropertiesCtorParams[2] = wifiSettings
                        .getProxyExceptions();
                // 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);
                setEnumField(config, "STATIC", "proxySettings");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    public static Object invokeDeclaredMethod(Class<?> clazz, Object object,
            String methodName, Class<?>[] args, Object[] argsValue)
            throws SecurityException, NoSuchMethodException,
            IllegalArgumentException, IllegalAccessException,
            InvocationTargetException, RemoteException {

        LogUtil.d(TAG, "Invoking declared method " + clazz.getSimpleName()
                + "." + methodName);
        Method privateMethod = clazz.getDeclaredMethod(methodName, args);
        privateMethod.setAccessible(true);
        Object result = privateMethod.invoke(object, argsValue);
        return result;
    }


    private static void setEnumField(Object object, String value, String name)
            throws SecurityException, NoSuchFieldException,
            IllegalArgumentException, IllegalAccessException {
        Field f = object.getClass().getField(name);
        f.set(object, Enum.valueOf((Class<Enum>) f.getType(), value));
    }

    public static Object getFieldValue(Class<?> clazz, Object object,
            String fieldName) {
        if (clazz == null || fieldName == null) {
            throw new IllegalArgumentException(
                    "Required argument can not be blank.");
        }
        Object result = null;
        try {
            Field f = clazz.getField(fieldName);
            f.setAccessible(true);
            result = f.get(object);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
        return result;
    }

编辑: API for LOLLIPOP [上面的api for proxy和ip不会在最新的Andriod L中使用]

 if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
            // Implementation for Proxy setting for LOLLIPOP
            try {
                URL proxyUrl = new URL(
                        addNetworkProxyProperties.getHttpProxyUri());
                String host = proxyUrl.getHost();
                int portStr = proxyUrl.getPort();
                String exclusionList = addNetworkProxyProperties
                        .getExceptions();
                Constructor<ProxyInfo> constructor = ProxyInfo.class
                        .getConstructor(new Class[] { String.class, int.class,
                                String.class });
                ProxyInfo mHttpProxy = constructor.newInstance(new Object[] {
                        host, portStr, exclusionList });
                Class ipConfigClass = Class
                        .forName("android.net.IpConfiguration");
                Object ipConfigObject = ipConfigClass.newInstance();
                Method setHttpProxy = ipConfigClass.getDeclaredMethod(
                        "setHttpProxy", ProxyInfo.class);
                setHttpProxy.setAccessible(true);
                setHttpProxy.invoke(ipConfigObject, mHttpProxy);
                Method getHttpProxySettings = ipConfigClass
                        .getDeclaredMethod("getProxySettings");
                getHttpProxySettings.setAccessible(true);
                Method setProxy = config.getClass().getDeclaredMethod(
                        "setProxy",
                        getHttpProxySettings.invoke(ipConfigObject).getClass(),
                        ProxyInfo.class);
                setProxy.setAccessible(true);
                setEnumField(ipConfigObject, "STATIC", "proxySettings");
                setProxy.invoke(config,
                        getHttpProxySettings.invoke(ipConfigObject), mHttpProxy);
            } catch (Exception e) {
                /*
                 * Excepted exceptions may be SecurityException,
                 * IllegalArgumentException, IllegalAccessException,
                 * InvocationTargetException, NoSuchMethodException,
                 * InstantiationException, ClassNotFoundException,
                 * NoSuchFieldException, MalformedURLException
                 */
                e.printStackTrace();
            }

        }