Android WebView代理无法设置

时间:2019-02-02 09:04:19

标签: android proxy

我试图在我的apl中为Webview设置代理。在github上使用this示例,但对我不起作用。 Logs表示已成功设置代理,但没有成功。我已经添加了互联网许可,并尝试了来自许多网站的许多代理。我正在棉花糖设备上进行调试 这是示例代码 我像这样使用

private static final String LOG_TAG = "ProxyUtils";

public static boolean setProxy(WebView webview, String host, int port) {

int sdkInt = Build.VERSION.SDK_INT;

if (sdkInt < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {

return setProxyPreICS(webview, host, port);

} else if (sdkInt < Build.VERSION_CODES.JELLY_BEAN) {

return setProxyICS(webview, host, port);

} else if (sdkInt < Build.VERSION_CODES.KITKAT) {

return setProxyJB(webview, host, port);

} else if (sdkInt < Build.VERSION_CODES.LOLLIPOP) {

return setProxyKK(webview, host, port, "android.app.Application");

} else {

return setProxyLollipop(webview.getContext(), host, port);

}

}

public static boolean clearProxy(WebView webView) {

int sdkInt = Build.VERSION.SDK_INT;

if (sdkInt < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {

return setProxyPreICS(webView, null,0);

} else if (sdkInt < Build.VERSION_CODES.JELLY_BEAN) {

return setProxyICS(webView, null, 0);

} else if (sdkInt < Build.VERSION_CODES.KITKAT) {

return setProxyJB(webView, null,0);

} else if (sdkInt < Build.VERSION_CODES.LOLLIPOP) {

return setProxyKK(webView, null, 0, "android.app.Application");

} else {

return setProxyLollipop(webView.getContext(), null, 0);

}

}

private static boolean setProxyPreICS(WebView webView, String host, final int port) {

HttpHost proxyServer ;

if (null == host) {

proxyServer = null;

} else {

proxyServer = new HttpHost(host, port);

}

Class networkClass = null;

Object network = null;

try {

networkClass = Class.forName("android.webkit.Network");

if (networkClass == null) {

Log.e(LOG_TAG, "failed to get class for android.webkit.Network");

return false;

}

Method getInstanceMethod = networkClass.getMethod("getInstance", Context.class);

if (getInstanceMethod == null) {

Log.e(LOG_TAG, "failed to get getInstance method");

}

network = getInstanceMethod.invoke(networkClass, new Object[]{webView.getContext()});

} catch (Exception ex) {

Log.e(LOG_TAG, "error getting network: " + ex);

return false;

}

if (network == null) {

Log.e(LOG_TAG, "error getting network: network is null");

return false;

}

Object requestQueue = null;

try {

Field requestQueueField = networkClass

.getDeclaredField("mRequestQueue");

requestQueue = getFieldValueSafely(requestQueueField, network);

} catch (Exception ex) {

Log.e(LOG_TAG, "error getting field value");

return false;

}

if (requestQueue == null) {

Log.e(LOG_TAG, "Request queue is null");

return false;

}

Field proxyHostField = null;

try {

Class requestQueueClass = Class.forName("android.net.http.RequestQueue");

proxyHostField = requestQueueClass

.getDeclaredField("mProxyHost");

} catch (Exception ex) {

Log.e(LOG_TAG, "error getting proxy host field");

return false;

}

boolean temp = proxyHostField.isAccessible();

try {

proxyHostField.setAccessible(true);

proxyHostField.set(requestQueue, proxyServer);

} catch (Exception ex) {

Log.e(LOG_TAG, "error setting proxy host");

} finally {

proxyHostField.setAccessible(temp);

}

Log.d(LOG_TAG, "Setting proxy with <= 3.2 API successful!");

return true;

}

@SuppressWarnings("all")

private static boolean setProxyICS(WebView webview, String host, int port) {

try {

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;

}

}

/**

* Set Proxy for Android 4.1 - 4.3.

*/

@SuppressWarnings("all")

private static boolean setProxyJB(WebView webview, String host, int port) {

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;

}

// from https://stackoverflow.com/questions/19979578/android-webview-set-proxy-programatically-kitkat

@SuppressLint("NewApi")

@SuppressWarnings("all")

private static boolean setProxyKK(WebView webView, String host, int port, String applicationClassName) {

Context appContext = webView.getContext().getApplicationContext();

if (null == host) {

System.clearProperty("http.proxyHost");

System.clearProperty("http.proxyPort");

System.clearProperty("https.proxyHost");

System.clearProperty("https.proxyPort");

} else {

System.setProperty("http.proxyHost", host);

System.setProperty("http.proxyPort", port + "");

System.setProperty("https.proxyHost", host);

System.setProperty("https.proxyPort", port + "");

}

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);

Map receivers = (Map) receiversField.get(loadedApk);

for (Object receiverMap : receivers.values()) {

for (Object rec : ((Map) 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);

/*********** optional, may be need in future *************/

final String CLASS_NAME = "android.net.ProxyProperties";

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);

/*********** optional, may be need in future *************/

onReceiveMethod.invoke(rec, appContext, intent);

}

}

}

Log.d(LOG_TAG, "Setting proxy with >= 4.4 API successful!");

return true;

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (NoSuchFieldException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (IllegalArgumentException e) {

e.printStackTrace();

} catch (NoSuchMethodException e) {

e.printStackTrace();

} catch (InvocationTargetException e) {

e.printStackTrace();

} catch (InstantiationException e) {

e.printStackTrace();

}

return false;

}

private static boolean setProxyLollipop(final Context context, String host, int port) {

Log.i(LOG_TAG, "setProxyLollipop");

if (null == host) {

System.clearProperty("http.proxyHost");

System.clearProperty("http.proxyPort");

} else {

System.setProperty("http.proxyHost", host);

System.setProperty("http.proxyPort", port + "");

}

try {

Context appContext = context.getApplicationContext();

Class applicationClass = Class.forName("android.app.Application");

Field mLoadedApkField = applicationClass.getDeclaredField("mLoadedApk");

mLoadedApkField.setAccessible(true);

Object mloadedApk = mLoadedApkField.get(appContext);

Class loadedApkClass = Class.forName("android.app.LoadedApk");

Field mReceiversField = loadedApkClass.getDeclaredField("mReceivers");

mReceiversField.setAccessible(true);

Map receivers = (Map) mReceiversField.get(mloadedApk);

for (Object receiverMap : receivers.values()) {

for (Object receiver : ((Map) receiverMap).keySet()) {

Class clazz = receiver.getClass();

if (clazz.getName().contains("ProxyChangeListener")) {

Method onReceiveMethod = clazz.getDeclaredMethod("onReceive", Context.class, Intent.class);

Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);

onReceiveMethod.invoke(receiver, appContext, intent);

}

}

}

Log.i(LOG_TAG, "Lollipop successfully");

return true;

} catch (Exception e) {

e.printStackTrace();

}

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;

}

}

课程     公共类ProxyUtils {

component.vue

0 个答案:

没有答案