Manual Proxy in Android through reflection

微笑、不失礼 提交于 2019-12-17 20:24:53

问题


I am trying to set ssid,proxy,ipsetting in android through reflection and i m successfully for ssid and brief ip settings in android via reflection , my issue is i want to set proxy settings programtically via reflection and most of the code i goggled say implementation of STATIC and NONE options but devices i hv proxy options as NONE and MANUAL is both same ? below is code for my proxy plz suggest what exactly should i change to work for manual proxy implementation :

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:


I have written below apis for proxy in android via reflection :

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

EDIT : API FOR LOLLIPOP [the above api for proxy and ip wont work in latest 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();
            }

        }


来源:https://stackoverflow.com/questions/24697533/manual-proxy-in-android-through-reflection

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