微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Android中的手动代理通过反射

我试图在 android中通过反射设置ssid,proxy,ipsetting并成功通过反射在android中通过ssid和简短的ip设置,我的问题是我想通过反射程序设置代理设置和大部分代码我goggled说实现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");
    }

解决方法

我通过反思在android下面写了代理apis:

/**
         * 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,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,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(),"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,"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,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(),"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,"addDns",new Class[] { inetAddressClass },new Object[] { inetAddressDns1 });
                invokeDeclaredMethod(linkPropertiesClass,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,"proxySettings");
            } catch (Exception e) {
                e.printstacktrace();
            }
        }

    public static Object invokeDeclaredMethod(Class<?> clazz,Object object,String methodName,Class<?>[] args,Object[] argsValue)
            throws SecurityException,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,illegalaccessexception {
        Field f = object.getClass().getField(name);
        f.set(object,Enum.valueOf((Class<Enum>) f.getType(),value));
    }

    public static Object getFieldValue(Class<?> clazz,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,"proxySettings");
                setProxy.invoke(config,getHttpProxySettings.invoke(ipConfigObject),mHttpProxy);
            } catch (Exception e) {
                /*
                 * Excepted exceptions may be SecurityException,* IllegalArgumentException,* InvocationTargetException,* InstantiationException,* NoSuchFieldException,MalformedURLException
                 */
                e.printstacktrace();
            }

        }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐