这几天在开发一个项目、关于用webvIEw设置代理后访问页面。于是整理出来。亲测可用
package com.sh.util;import androID.annotation.Suppresslint;import androID.content.Context;import androID.content.Intent;import androID.net.Proxy;import androID.os.Build;import androID.os.Parcelable;import androID.text.TextUtils;import androID.util.ArrayMap;import androID.util.Log;import androID.webkit.WebVIEw;import java.io.PrintWriter;import java.io.StringWriter;import java.lang.reflect.Constructor;import java.lang.reflect.FIEld;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.net.Authenticator;import java.net.PasswordAuthentication;import java.util.PropertIEs;public class WebVIEwPxoxyUtils { private static final String LOG_TAG = "WebvIEwSettingProxy"; /** * 给webvIEw设置代理 * * @param webvIEw * @param host ip * @param port 端口 * @param applicationClassname 注意这里applicationClassname 传递的是 application 的类名 * @return */ public static boolean setProxy(WebVIEw webvIEw, String host, int port, String applicationClassname, String username, String pwd) { // ICS: 4.0 if (Build.VERSION.SDK_INT <= 15) { return setProxyICS(webvIEw, host, port); } // 4.1-4.3 (JB) else if (Build.VERSION.SDK_INT <= 18) { return setProxyJB(webvIEw, host, port); } // 4.4 (KK) & 5.0 (Lollipop) else { return setProxyKKPlus(webvIEw, host, port, applicationClassname,username,pwd); } } /** * 给webvIEw取消代理 * * @param webvIEw * @param applicationClassname 注意这里applicationClassname 传递的是 androID.app.Application * @return */ public static boolean revertBackProxy(WebVIEw webvIEw, String applicationClassname) { if (webvIEw == null || TextUtils.isEmpty(applicationClassname)) { return true; } // 3.2 (HC) or lower // ICS: 4.0 else if (Build.VERSION.SDK_INT <= 15) { return revertProxyICS(webvIEw); } // 4.1-4.3 (JB) else if (Build.VERSION.SDK_INT <= 18) { return revertProxyJB(webvIEw); } // 4.4 (KK) & 5.0 (Lollipop) else { return revertProxyKKPlus(webvIEw, applicationClassname); } } /** * Set Proxy for AndroID 3.2 and below. */ @SuppressWarnings("all") private static boolean setProxyICS(WebVIEw webvIEw, String host, int port) { try { Log.d(LOG_TAG, "Setting proxy with 4.0 API."); Class jwcjb = Class.forname("androID.webkit.JWebCoreJavaBrIDge"); Class params[] = new Class[1]; params[0] = Class.forname("androID.net.ProxyPropertIEs"); Method updateProxyInstance = jwcjb.getDeclaredMethod("updateProxy", params); Class wv = Class.forname("androID.webkit.WebVIEw"); FIEld mWebVIEwCoreFIEld = wv.getDeclaredFIEld("mWebVIEwCore"); Object mWebVIEwCoreFIEldInstance = getFIEldValueSafely(mWebVIEwCoreFIEld, webvIEw); Class wvc = Class.forname("androID.webkit.WebVIEwCore"); FIEld mbrowserFrameFIEld = wvc.getDeclaredFIEld("mbrowserFrame"); Object mbrowserFrame = getFIEldValueSafely(mbrowserFrameFIEld, mWebVIEwCoreFIEldInstance); Class bf = Class.forname("androID.webkit.browserFrame"); FIEld sJavaBrIDgeFIEld = bf.getDeclaredFIEld("sJavaBrIDge"); Object sJavaBrIDge = getFIEldValueSafely(sJavaBrIDgeFIEld, mbrowserFrame); Class ppclass = Class.forname("androID.net.ProxyPropertIEs"); Class pparams[] = new Class[3]; pparams[0] = String.class; pparams[1] = int.class; pparams[2] = String.class; Constructor ppcont = ppclass.getConstructor(pparams); updateProxyInstance.invoke(sJavaBrIDge, ppcont.newInstance(host, port, null)); Log.d(LOG_TAG, "Setting proxy with 4.0 API successful!"); return true; } catch (Exception ex) { Log.e(LOG_TAG, "Failed to set http proxy: " + ex); return false; } } private static boolean revertProxyICS(WebVIEw webvIEw) { try { Log.d(LOG_TAG, "Setting proxy with 4.0 API."); Class jwcjb = Class.forname("androID.webkit.JWebCoreJavaBrIDge"); Class params[] = new Class[1]; params[0] = Class.forname("androID.net.ProxyPropertIEs"); Method updateProxyInstance = jwcjb.getDeclaredMethod("updateProxy", params); Class wv = Class.forname("androID.webkit.WebVIEw"); FIEld mWebVIEwCoreFIEld = wv.getDeclaredFIEld("mWebVIEwCore"); Object mWebVIEwCoreFIEldInstance = getFIEldValueSafely(mWebVIEwCoreFIEld, webvIEw); Class wvc = Class.forname("androID.webkit.WebVIEwCore"); FIEld mbrowserFrameFIEld = wvc.getDeclaredFIEld("mbrowserFrame"); Object mbrowserFrame = getFIEldValueSafely(mbrowserFrameFIEld, mWebVIEwCoreFIEldInstance); Class bf = Class.forname("androID.webkit.browserFrame"); FIEld sJavaBrIDgeFIEld = bf.getDeclaredFIEld("sJavaBrIDge"); Object sJavaBrIDge = getFIEldValueSafely(sJavaBrIDgeFIEld, mbrowserFrame); Class ppclass = Class.forname("androID.net.ProxyPropertIEs"); Class pparams[] = new Class[3]; pparams[0] = String.class; pparams[1] = int.class; pparams[2] = String.class; Constructor ppcont = ppclass.getConstructor(pparams); Object o = null; updateProxyInstance.invoke(sJavaBrIDge, o); Log.d(LOG_TAG, "Setting proxy with 4.0 API successful!"); return true; } catch (Exception ex) { Log.e(LOG_TAG, "Failed to set http proxy: " + ex); return false; } } /** * Set Proxy for AndroID 4.1 - 4.3. */ @SuppressWarnings("all") private static boolean setProxyJB(WebVIEw webvIEw, String host, int port) { Log.d(LOG_TAG, "Setting proxy with 4.1 - 4.3 API."); try { Class wvcclass = Class.forname("androID.webkit.WebVIEwClassic"); Class wvParams[] = new Class[1]; wvParams[0] = Class.forname("androID.webkit.WebVIEw"); Method fromWebVIEw = wvcclass.getDeclaredMethod("fromWebVIEw", wvParams); Object webVIEwClassic = fromWebVIEw.invoke(null, webvIEw); Class wv = Class.forname("androID.webkit.WebVIEwClassic"); FIEld mWebVIEwCoreFIEld = wv.getDeclaredFIEld("mWebVIEwCore"); Object mWebVIEwCoreFIEldInstance = getFIEldValueSafely(mWebVIEwCoreFIEld, webVIEwClassic); Class wvc = Class.forname("androID.webkit.WebVIEwCore"); FIEld mbrowserFrameFIEld = wvc.getDeclaredFIEld("mbrowserFrame"); Object mbrowserFrame = getFIEldValueSafely(mbrowserFrameFIEld, mWebVIEwCoreFIEldInstance); Class bf = Class.forname("androID.webkit.browserFrame"); FIEld sJavaBrIDgeFIEld = bf.getDeclaredFIEld("sJavaBrIDge"); Object sJavaBrIDge = getFIEldValueSafely(sJavaBrIDgeFIEld, mbrowserFrame); Class ppclass = Class.forname("androID.net.ProxyPropertIEs"); Class pparams[] = new Class[3]; pparams[0] = String.class; pparams[1] = int.class; pparams[2] = String.class; Constructor ppcont = ppclass.getConstructor(pparams); Class jwcjb = Class.forname("androID.webkit.JWebCoreJavaBrIDge"); Class params[] = new Class[1]; params[0] = Class.forname("androID.net.ProxyPropertIEs"); Method updateProxyInstance = jwcjb.getDeclaredMethod("updateProxy", params); updateProxyInstance.invoke(sJavaBrIDge, ppcont.newInstance(host, port, null)); } catch (Exception ex) { Log.e(LOG_TAG, "Setting proxy with >= 4.1 API Failed with error: " + ex.getMessage()); return false; } Log.d(LOG_TAG, "Setting proxy with 4.1 - 4.3 API successful!"); return true; } private static boolean revertProxyJB(WebVIEw webvIEw) { Log.d(LOG_TAG, "revert proxy with 4.1 - 4.3 API."); try { Class wvcclass = Class.forname("androID.webkit.WebVIEwClassic"); Class wvParams[] = new Class[1]; wvParams[0] = Class.forname("androID.webkit.WebVIEw"); Method fromWebVIEw = wvcclass.getDeclaredMethod("fromWebVIEw", wvParams); Object webVIEwClassic = fromWebVIEw.invoke(null, webvIEw); Class wv = Class.forname("androID.webkit.WebVIEwClassic"); FIEld mWebVIEwCoreFIEld = wv.getDeclaredFIEld("mWebVIEwCore"); Object mWebVIEwCoreFIEldInstance = getFIEldValueSafely(mWebVIEwCoreFIEld, webVIEwClassic); Class wvc = Class.forname("androID.webkit.WebVIEwCore"); FIEld mbrowserFrameFIEld = wvc.getDeclaredFIEld("mbrowserFrame"); Object mbrowserFrame = getFIEldValueSafely(mbrowserFrameFIEld, mWebVIEwCoreFIEldInstance); Class bf = Class.forname("androID.webkit.browserFrame"); FIEld sJavaBrIDgeFIEld = bf.getDeclaredFIEld("sJavaBrIDge"); Object sJavaBrIDge = getFIEldValueSafely(sJavaBrIDgeFIEld, mbrowserFrame); Class ppclass = Class.forname("androID.net.ProxyPropertIEs"); Class pparams[] = new Class[3]; pparams[0] = String.class; pparams[1] = int.class; pparams[2] = String.class; Constructor ppcont = ppclass.getConstructor(pparams); Class jwcjb = Class.forname("androID.webkit.JWebCoreJavaBrIDge"); Class params[] = new Class[1]; params[0] = Class.forname("androID.net.ProxyPropertIEs"); Method updateProxyInstance = jwcjb.getDeclaredMethod("updateProxy", params); Object o = null; updateProxyInstance.invoke(sJavaBrIDge, o); } catch (Exception ex) { Log.e(LOG_TAG, "Setting proxy with >= 4.1 API Failed with error: " + ex.getMessage()); return false; } Log.d(LOG_TAG, "revert proxy with 4.1 - 4.3 API successful!"); return true; } // from https://stackoverflow.com/questions/19979578/androID-webvIEw-set-proxy-programatically-kitkat @Suppresslint("NewAPI") @SuppressWarnings("all") private static boolean setProxyKKPlus(WebVIEw webVIEw, String host, int port, String applicationClassname, final String username, final String pwd) { Log.d(LOG_TAG, "Setting proxy with >= 4.4 API."); Context appContext = webVIEw.getContext().getApplicationContext(); System.setProperty("http.proxyHost", host); System.setProperty("http.proxyPort", port + ""); System.setProperty("https.proxyHost", host); System.setProperty("https.proxyPort", port + ""); Authenticator.setDefault( new Authenticator() { @OverrIDe public PasswordAuthentication getpasswordAuthentication() { return new PasswordAuthentication( username, pwd.tochararray()); } } ); try { if (StringUtils.isNotBlank(username) && StringUtils.isNotBlank(pwd)) { System.setProperty("http.proxyUser", username); System.setProperty("http.proxyPassword", pwd); System.setProperty("https.proxyUser", username); System.setProperty("https.proxyPassword", pwd); } Class applictionCls = Class.forname(applicationClassname); FIEld loadedApkFIEld = applictionCls.getFIEld("mloadedApk"); loadedApkFIEld.setAccessible(true); Object loadedApk = loadedApkFIEld.get(appContext); Class loadedApkCls = Class.forname("androID.app.LoadedApk"); FIEld receiversFIEld = loadedApkCls.getDeclaredFIEld("mReceivers"); receiversFIEld.setAccessible(true); ArrayMap receivers = (ArrayMap) receiversFIEld.get(loadedApk); for (Object receiverMap : receivers.values()) { for (Object rec : ((ArrayMap) receiverMap).keySet()) { Class clazz = rec.getClass(); if (clazz.getname().contains("Proxychangelistener")) { Method onReceiveMethod = clazz.getDeclaredMethod("onReceive", Context.class, Intent.class); Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION); final String CLASS_name = "androID.net.ProxyInfo"; Class cls = Class.forname(CLASS_name); Constructor constructor = cls.getConstructor(String.class, Integer.TYPE, String.class); constructor.setAccessible(true); Object proxyPropertIEs = constructor.newInstance(host, port, null); intent.putExtra("proxy", (Parcelable) proxyPropertIEs); onReceiveMethod.invoke(rec, appContext, intent); } } } Log.d(LOG_TAG, "Setting proxy with >= 4.4 API successful!"); return true; } catch (ClassNotFoundException e) { StringWriter sw = new StringWriter(); e.printstacktrace(new PrintWriter(sw)); String exceptionAsstring = sw.toString(); Log.v(LOG_TAG, e.getMessage()); Log.v(LOG_TAG, exceptionAsstring); } catch (NoSuchFIEldException e) { StringWriter sw = new StringWriter(); e.printstacktrace(new PrintWriter(sw)); String exceptionAsstring = sw.toString(); Log.v(LOG_TAG, e.getMessage()); Log.v(LOG_TAG, exceptionAsstring); } catch (illegalaccessexception e) { StringWriter sw = new StringWriter(); e.printstacktrace(new PrintWriter(sw)); String exceptionAsstring = sw.toString(); Log.v(LOG_TAG, e.getMessage()); Log.v(LOG_TAG, exceptionAsstring); } catch (IllegalArgumentException e) { StringWriter sw = new StringWriter(); e.printstacktrace(new PrintWriter(sw)); String exceptionAsstring = sw.toString(); Log.v(LOG_TAG, e.getMessage()); Log.v(LOG_TAG, exceptionAsstring); } catch (NoSuchMethodException e) { StringWriter sw = new StringWriter(); e.printstacktrace(new PrintWriter(sw)); String exceptionAsstring = sw.toString(); Log.v(LOG_TAG, e.getMessage()); Log.v(LOG_TAG, exceptionAsstring); } catch (InvocationTargetException e) { StringWriter sw = new StringWriter(); e.printstacktrace(new PrintWriter(sw)); String exceptionAsstring = sw.toString(); Log.v(LOG_TAG, e.getMessage()); Log.v(LOG_TAG, exceptionAsstring); } catch (InstantiationException e) { StringWriter sw = new StringWriter(); e.printstacktrace(new PrintWriter(sw)); String exceptionAsstring = sw.toString(); Log.v(LOG_TAG, e.getMessage()); Log.v(LOG_TAG, exceptionAsstring); } return false; } @Suppresslint("NewAPI") @SuppressWarnings("all") private static boolean revertProxyKKPlus(WebVIEw webVIEw, String applicationClassname) { Context appContext = webVIEw.getContext().getApplicationContext(); PropertIEs propertIEs = System.getPropertIEs(); propertIEs.remove("http.proxyHost"); propertIEs.remove("http.proxyPort"); propertIEs.remove("https.proxyHost"); propertIEs.remove("https.proxyPort"); propertIEs.remove("http.proxyUser"); propertIEs.remove("http.proxyPassword"); propertIEs.remove("https.proxyUser"); propertIEs.remove("https.proxyPassword"); try { Class applictionCls = Class.forname(applicationClassname); FIEld loadedApkFIEld = applictionCls.getFIEld("mloadedApk"); loadedApkFIEld.setAccessible(true); Object loadedApk = loadedApkFIEld.get(appContext); Class loadedApkCls = Class.forname("androID.app.LoadedApk"); FIEld receiversFIEld = loadedApkCls.getDeclaredFIEld("mReceivers"); receiversFIEld.setAccessible(true); ArrayMap receivers = (ArrayMap) receiversFIEld.get(loadedApk); for (Object receiverMap : receivers.values()) { for (Object rec : ((ArrayMap) receiverMap).keySet()) { Class clazz = rec.getClass(); if (clazz.getname().contains("Proxychangelistener")) { Method onReceiveMethod = clazz.getDeclaredMethod("onReceive", Context.class, Intent.class); Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION); final String CLASS_name = "androID.net.ProxyInfo"; Class cls = Class.forname(CLASS_name); Constructor constructor = cls.getConstructor(String.class, Integer.TYPE, String.class); constructor.setAccessible(true); Object proxyPropertIEs = constructor.newInstance(null, 0, null); intent.putExtra("proxy", (Parcelable) proxyPropertIEs); onReceiveMethod.invoke(rec, appContext, intent); } } } Log.d(LOG_TAG, "revert proxy with >= 4.4 API successful!"); return true; } catch (ClassNotFoundException e) { StringWriter sw = new StringWriter(); e.printstacktrace(new PrintWriter(sw)); String exceptionAsstring = sw.toString(); Log.v(LOG_TAG, e.getMessage()); Log.v(LOG_TAG, exceptionAsstring); } catch (NoSuchFIEldException e) { StringWriter sw = new StringWriter(); e.printstacktrace(new PrintWriter(sw)); String exceptionAsstring = sw.toString(); Log.v(LOG_TAG, e.getMessage()); Log.v(LOG_TAG, exceptionAsstring); } catch (illegalaccessexception e) { StringWriter sw = new StringWriter(); e.printstacktrace(new PrintWriter(sw)); String exceptionAsstring = sw.toString(); Log.v(LOG_TAG, e.getMessage()); Log.v(LOG_TAG, exceptionAsstring); } catch (IllegalArgumentException e) { StringWriter sw = new StringWriter(); e.printstacktrace(new PrintWriter(sw)); String exceptionAsstring = sw.toString(); Log.v(LOG_TAG, e.getMessage()); Log.v(LOG_TAG, exceptionAsstring); } catch (NoSuchMethodException e) { StringWriter sw = new StringWriter(); e.printstacktrace(new PrintWriter(sw)); String exceptionAsstring = sw.toString(); Log.v(LOG_TAG, e.getMessage()); Log.v(LOG_TAG, exceptionAsstring); } catch (InvocationTargetException e) { StringWriter sw = new StringWriter(); e.printstacktrace(new PrintWriter(sw)); String exceptionAsstring = sw.toString(); Log.v(LOG_TAG, e.getMessage()); Log.v(LOG_TAG, exceptionAsstring); } catch (InstantiationException e) { StringWriter sw = new StringWriter(); e.printstacktrace(new PrintWriter(sw)); String exceptionAsstring = sw.toString(); Log.v(LOG_TAG, e.getMessage()); Log.v(LOG_TAG, exceptionAsstring); } return false; } private static Object getFIEldValueSafely(FIEld fIEld, Object classInstance) throws IllegalArgumentException, illegalaccessexception { boolean oldAccessibleValue = fIEld.isAccessible(); fIEld.setAccessible(true); Object result = fIEld.get(classInstance); fIEld.setAccessible(oldAccessibleValue); return result; } public static boolean isWifiProxy(Context context) { 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 = Proxy.getHost(context); proxyPort = Proxy.getPort(context); } return (!TextUtils.isEmpty(proxyAddress)) && (proxyPort != -1); }}
判断是否使用代理的方法:
public static boolean isWifiProxy(Context context) { 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); } return (!TextUtils.isEmpty(proxyAddress)) && (proxyPort != -1); }
但是我发现,如果用webvIEw设置代理,不加代理认证的话,有时候也是打不开页面的,这一块各位如果有更好的解决办法、可以一起讨论学习下
总结以上是内存溢出为你收集整理的关于android-webview设置代理访问页面全部内容,希望文章能够帮你解决关于android-webview设置代理访问页面所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)