web-dev-qa-db-fra.com

WebView proxy Android

Je sais comment configurer le proxy manuellement et l'utiliser dans mon WebView.

Paramètres -> Réseaux sans fil -> Réseaux mobiles-> Noms des points d'accès-> telkila. Maintenant, entrez l'adresse du serveur proxy et le port (qui sera 80) . WebView.enablePlatformNotifications ();

Mais puis-je définir le paramètre de proxy à partir du code? Donc, mon utilisateur n'a pas à définir manuellement?

Merci

36
user430926

Il n’existe aucun moyen légal de modifier vos paramètres de proxy Webview par programme. Mais il est possible d'utiliser la réflexion Java pour modifier la valeur mProxyHost de la classe Android.net.http.RequestQueue. C'est une valeur privée et il n'y a pas de régleurs pour cela, donc la réflexion semble être la seule variante possible. Je l'ai utilisé dans mon projet et ça marche. Voici l'échantillon de ma méthode:

    private boolean setProxyHostField(HttpHost proxyServer) {
    // Getting network      
    Class networkClass = null;
    Object network = null;
    try {
        networkClass = Class.forName("Android.webkit.Network");
        Field networkField = networkClass.getDeclaredField("sNetwork");
        network = getFieldValueSafely(networkField, null);
    } catch (Exception ex) {
        Log.e(ProxyManager.class.getName(), "error getting network");
        return false;
    }
    if (network == null) {
        Log.e(ProxyManager.class.getName(), "error getting network : null");
        return false;
    }
    Object requestQueue = null;
    try {
        Field requestQueueField = networkClass
                .getDeclaredField("mRequestQueue");
        requestQueue = getFieldValueSafely(requestQueueField, network);
    } catch (Exception ex) {
        Log.e(ProxyManager.class.getName(), "error getting field value");
        return false;
    }
    if (requestQueue == null) {
        Log.e(ProxyManager.class.getName(), "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(ProxyManager.class.getName(), "error getting proxy Host field");
        return false;
    }       
    synchronized (synchronizer) {
        boolean temp = proxyHostField.isAccessible();
        try {
            proxyHostField.setAccessible(true);
            proxyHostField.set(requestQueue, proxyServer);
        } catch (Exception ex) {
            Log.e(ProxyManager.class.getName(), "error setting proxy Host");
        } finally {
            proxyHostField.setAccessible(temp);
        }
    }
    return true;
}

private 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;      
}
22
birdy

J'ai adapté les trois solutions présentées ici (et modifiée en cas d'échec) pour produire une seule méthode setProxy qui fonctionne pour toutes les versions d'Android. Je l'ai testé de 10 à 18 ans, et cela fonctionne dans tous les environnements testés.

MIS À JOUR 2014-04-04 J'ai enfin travaillé sur la solution à partir d'un commentaire ci-dessous, avec l'aimable autorisation de nubela et xjy2061. Maintenant, cela fonctionne pour toutes les versions actuelles d'Android, y compris KitKat 4.4. Si vous implémentez votre propre sous-classe Application, indiquez le nom de la classe en tant que quatrième paramètre facultatif.

UPDATED 2015-01-15 La partie facultative de la méthode KitKat lève une exception sur Lollipop, car une classe auxiliaire est manquante, mais elle fonctionne aussi bien sur KitKat que sur Lollipop, car WebView est basé sur Chromium cas.

public static boolean setProxy(WebView webview, String Host, int port, String applicationClassName="Android.app.Application") {
    // 3.2 (HC) or lower
    if (Build.VERSION.SDK_INT <= 13) {
        return setProxyUpToHC(webview, Host, port);
    }
    // ICS: 4.0
    else 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);
    }
}

/**
 * Set Proxy for Android 3.2 and below.
 */
@SuppressWarnings("all")
private static boolean setProxyUpToHC(WebView webview, String Host, int port) {
    Log.d(LOG_TAG, "Setting proxy with <= 3.2 API.");

    HttpHost proxyServer = new HttpHost(Host, port);
    // Getting network
    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
    {
        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;
    }
}

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

// 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) {
    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(Proxy.PROXY_CHANGE_ACTION);

                    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);
    } 
    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;
}
29
Jimmy Dee

J'ai fait beaucoup de tests et je peux dire que la réponse précédente utilisant le remplacement basé sur Android.net.http.RequestQueue fonctionne parfaitement d'Android 1.6 à 3.1.

Mais il y avait un refactoring de code sur l'API et pour le faire fonctionner sur Android 3.2 & 4.x, voici la solution:

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 mWebViewCoreFieldIntance = getFieldValueSafely(mWebViewCoreField, oauthPage);

  Class wvc = Class.forName("Android.webkit.WebViewCore");
  Field mBrowserFrameField = wvc.getDeclaredField("mBrowserFrame");
  Object mBrowserFrame = getFieldValueSafely(mBrowserFrameField, mWebViewCoreFieldIntance);

  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("my.proxy.com", 1234, null)); 
}
catch (Exception ex)
{    
}

prendre plaisir

9
Guillaume13

Comme @Karthik l'a dit, ces réponses ne fonctionnent pas sur Android 4.4 (KitKat) . Pour KitKat, la réponse a été publiée ici .

3
xjy2061

Ceci est le code pour les versions 4.1 et 4.2 - 

/**
 * Set Proxy for Android 4.1 and above.
 */
public static boolean setProxyICSPlus(WebView webview, String Host, int port, String exclusionList) {

    Log.d("", "Setting proxy with >= 4.1 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 mWebViewCoreFieldIntance = getFieldValueSafely(mWebViewCoreField, webViewClassic);

        Class wvc = Class.forName("Android.webkit.WebViewCore");
        Field mBrowserFrameField = wvc.getDeclaredField("mBrowserFrame");
        Object mBrowserFrame = getFieldValueSafely(mBrowserFrameField, mWebViewCoreFieldIntance);

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

    } catch (Exception ex) {
        Log.e("","Setting proxy with >= 4.1 API failed with error: " + ex.getMessage());
        return false;
    }

    Log.d("", "Setting proxy with >= 4.1 API successful!");
    return true;
}
1
MediumOne

Chromium a commencé à masquer les noms de classe dans la nouvelle version (le nom de classe de ProxyChangeListener semble être "bMh" dans la dernière version et pourrait changer dans les prochaines versions. La solution de Jimmy Dee ne fonctionnera donc plus pour les nouvelles versions. versions car la vérification suivante échouera toujours:

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

Une solution à laquelle j'ai pensé consiste à invoquer onReceive sur tous les récepteurs de diffusion dans le contexte d'application actuel.

Maintenant, je comprends que ce n’est pas une solution idéale, car elle peut avoir des effets secondaires indésirables en invoquant les mauvais récepteurs. Par conséquent, vous devez examiner tous les récepteurs de diffusion dans le contexte de l’application pour vous assurer qu’ils ne font rien de mal. (D'autres idées?)

En se basant sur la réponse précédente, cela ressemblerait à ceci:

// 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, Context appContext) {
    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);
        ArrayMap contextReceivers = (ArrayMap) receivers.get(appContext);
        for (Object rec : contextReceivers.keySet()) {
            Class clazz = rec.getClass();

            Method onReceiveMethod = clazz.getDeclaredMethod("onReceive", Context.class, Intent.class);
            Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
            try {
                onReceiveMethod.invoke(rec, appContext, intent);
            } catch (Exception e) {
                // oops, couldn't invoke this receiver
            }
        }


        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);
    } 
    return false;
}

Ce sera vraiment utile si quelqu'un dans la communauté a une meilleure idée.

0
Amer Sheeny

solution madeye https://Gist.github.com/madeye/2297083 pseudocode:

Android.webkit.Network.getInstance().mRequestQueue.mProxyHost=new HttpHost(Host, port, "http")    //sdk < 14
Android.webkit.WebViewCore.sendStaticMessage(new Android.net.ProxyProperties(...))   //sdk >= 14

est meilleur que la réponse de Birdy ( proxy WebView Android ) pseudocode:

Android.webkit.Network.sNetwork.mRequestQueue.mProxyHost=new HttpHost(Host, port, "http")    //sdk < 14

et mieux que les réponses de Guillaume13 et MediumOne ( proxy WebView Android ) pseudocode:

Android.webkit.JWebCoreJavaBridge.updateProxy(Android.webkit.WebViewClassic.fromWebView(webview).mWebViewCore.mBrowserFrame.sJavaBridge, new Android.net.ProxyProperties(...))   //sdk >= 14

mais je ne sais pas pourquoi que le proxy réussisse seulement quand j'insère deux lignes avant setProxy:

webview1.loadUrl("http://0.0.0.0");
try {Thread.sleep(100);} catch (Exception e) {}
ProxySettings.setProxy(getApplicationContext(), "192.168.0.109", 8081);
webview1.loadUrl("http://www.google.com/index.php");
0
diyism

Tout d'abord, merci à vous tous pour les codes postaux permettant de fixer les paramètres de proxy, qui n'existent pas après les modifications apportées à Android, cela m'a également beaucoup aidé. J'ai couvert les problèmes dans toutes les versions Android et je pense qu'il sera nécessaire de mettre à jour ces informations. Cela dépend de la réponse récapitulative de Jimmy ci-dessus (merci!). J'ai vérifié que son code ne fonctionnait pas correctement sous Android version 3.1 - 3.1 à cause de Android.net.ProxyProperties n'est pas pris en charge et que la méthode updateProxy need pour la réflexion ont seulement par passage Java.lang.String paramètre d'entrée. Donc, j'ai changé son code en passant, en espérant qu'il aidera les gens à avoir le même problème que moi:

/**
 * Set Proxy from 3.0.x - to 3.1.x API.
 * @param webview webview webview to apply proxy
 * @param Host host name of proxy server
 * @param port port of proxy server
 * @return true/false if success or not
 */
private static boolean setProxyOnlyHC30to31(WebView webview, String Host, int port) {
    try
    {
        Logger.d(ProxySettings.class, "Setting proxy from 3.0.x - 3.1.x API.");

        Class jwcjb = Class.forName("Android.webkit.JWebCoreJavaBridge");
        Class params[] = new Class[1];
        params[0] = Class.forName("Java.lang.String");
        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);

        updateProxyInstance.invoke(sJavaBridge, "http://" + Host + ":" + port);

        Logger.d(ProxySettings.class, "Setting proxy from 3.0.x - 3.1.x API successful!");
        return true;
    }
    catch (Exception ex)
    {
        if (Helper.DEBUG) Logger.e(ProxySettings.class, "failed to set HTTP proxy: " + ex);
        return false;
    }
}
0
Fuong Lee