Настройки прокси перестали работать после последнего обновления Android System Webview - PullRequest
0 голосов
/ 03 июня 2018

После последнего обновления Android System Webview (30 мая 2018 г.) настройки прокси перестали работать для меня, и прокси просто больше не работает для веб-просмотра.В других браузерах с прокси это тот же эффект, прокси не настроен, заблокированные сайты не открываются, ip не меняется.Возвращенная ошибка: либо хост не разрешен, либо соединение не установлено.Мое устройство - Nexus 5X, Android 8.1.0.Кто-нибудь еще сталкивался с такой же проблемой?

Я использую это для настройки прокси:

private static boolean setProxyKKPlus(WebView webView, String host, int port, String applicationClassName) {
        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 + "");
        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("android.intent.action.PROXY_CHANGE");

                        onReceiveMethod.invoke(rec, appContext, intent);
                    }
                }
            }

            Log.d(LOG_TAG, "Setting proxy with >= 4.4 API successful!");
            return true;
        } catch (Exception 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;
    }

Ответы [ 2 ]

0 голосов
/ 07 июля 2018

Чтобы расширить ответ, предоставленный @Anmerris, ниже приведен полный кодовый набор, который мне подходит.Я проверил его с помощью API 19–27, используя WebView 30.0.0.0–67.0.3396.87.

public static void setProxy(Context context, String proxyHost, String proxyPort) {
    // Set the proxy values
    System.setProperty("http.proxyHost", proxyHost);
    System.setProperty("http.proxyPort", proxyPort);
    System.setProperty("https.proxyHost", proxyHost);
    System.setProperty("https.proxyPort", proxyPort);

    // Use reflection to apply the new proxy values.
    try {
        // Get the application and APK classes.  Suppress the lint warning that reflection may not always work in the future and on all devices.
        Class applicationClass = Class.forName("android.app.Application");
        @SuppressLint("PrivateApi") Class loadedApkClass = Class.forName("android.app.LoadedApk");

        // Get the declared fields.  Suppress the lint warning that `mLoadedApk` cannot be resolved.
        @SuppressWarnings("JavaReflectionMemberAccess") Field mLoadedApkField = applicationClass.getDeclaredField("mLoadedApk");
        Field mReceiversField = loadedApkClass.getDeclaredField("mReceivers");

        // Allow the values to be changed.
        mLoadedApkField.setAccessible(true);
        mReceiversField.setAccessible(true);

        // Get the APK object.
        Object mLoadedApkObject = mLoadedApkField.get(context);

        // Get an array map of the receivers.
        ArrayMap receivers = (ArrayMap) mReceiversField.get(mLoadedApkObject);

        // Set the proxy.
        for (Object receiverMap : receivers.values()) {
            for (Object receiver : ((ArrayMap) receiverMap).keySet()) {
                // `Class<?>`, which is an `unbounded wildcard parameterized type`, must be used instead of `Class`, which is a `raw type`.  Otherwise, `receiveClass.getDeclaredMethod` is unhappy.
                Class<?> receiverClass = receiver.getClass();

                // Get the declared fields.
                final Field[] declaredFieldArray = receiverClass.getDeclaredFields();

                // Set the proxy for each field that is a `ProxyChangeListener`.
                for (Field field : declaredFieldArray) {
                    if (field.getType().getName().contains("ProxyChangeListener")) {
                        Method onReceiveMethod = receiverClass.getDeclaredMethod("onReceive", Context.class, Intent.class);
                        Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
                        onReceiveMethod.invoke(receiver, context, intent);
                    }
                }
            }
        }
    } catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException | NoSuchMethodException | InvocationTargetException exception) {
        Log.d("enableProxyThroughOrbot", "Exception: " + exception);
    }
}
0 голосов
/ 29 июня 2018

Этот код работает в моей среде (Chrome 67 + Android 7.0)

for (Object receiverMap : receivers.values()) {
    for (Object rec : ((ArrayMap) receiverMap).keySet()) {
        Class clazz = rec.getClass();

        boolean targetReceiverFound = false;
        if (clazz.getName().contains("ProxyChangeListener")) {
            targetReceiverFound = true;
        } else {
            final Field[] obfuscatedFields = clazz.getDeclaredFields();
            for (Field f : obfuscatedFields) {
                if (f.getType().getName().contains("ProxyChangeListener")) {
                    targetReceiverFound = true;
                    break;
                }
            }
        }

        if (targetReceiverFound) {
            // invoke onReceive() here
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...