40

Suppose I load a 3rd party URL through webview.

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        webview = (WebView) findViewById(R.id.webview);
        webview.setWebViewClient(new HelloWebViewClient());
        webview.getSettings().setJavaScriptEnabled(true);
        webview.setWebChromeClient(new MyWebChromeClient());
        webview.loadUrl("http://ebay.com");         
    }

Is it possible for me to inject something into this WebView to replace the ebay logo with my own?

TIMEX
  • 259,804
  • 351
  • 777
  • 1,080

4 Answers4

45

To expand on CommonsWare's correct answer:

WebView webview = new WebView();
webview.setWebViewClient(new WebClient());
webView.getSettings().setJavaScriptEnabled(true);
webview.loadUrl("stackoverflow.com");

then in WebClient:

public class WebClient extends WebViewClient {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        view.loadUrl(url);
        return true;
    }

    @Override
    public void onPageFinished(WebView view, String url) 
    {       
        // Obvious next step is: document.forms[0].submit()
        view.loadUrl("javascript:document.forms[0].q.value='[android]'");       
    }
}

In a nutshell, you wait for the page to load. Then you loadUrl("javascript:[your javascript here]").

Carlos Rendon
  • 6,174
  • 5
  • 34
  • 50
  • 2
    Make sure you set javascript enabled to true on your webview or you'll waste a lot of time trying to debug this like I did. – AdamMc331 Nov 27 '15 at 19:40
  • Why do you need to override shouldOverrideUrlLoading? – Bogdan Verbenets Apr 29 '16 at 19:45
  • 1
    I didn't need the `shouldOverrideUrlLoading` and instead of `view.loadUrl` looks like you need `view.evaluateJavascript("document.forms[0].q.value='[android]'", null)` – arekolek Jan 17 '19 at 21:58
  • Based on this answer I was able to come up with the following, which shows how to poke DOM to initialize fields on a form. https://github.com/slogan621/tscharts-register/blob/master/app/src/main/java/org/thousandsmiles/tschartsregister/CURPWebViewClient.java - thanks for the great answer that got me started. – slogan621 Dec 10 '20 at 23:13
13

Not directly. You can invoke Javascript code in the context of the current Web page, via loadUrl(), much like a bookmarklet does. However, you do not have direct access to the DOM from Java code.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Although the direct access part is true there is a full indirect access to Dom, using javaScriptBridge just pass the full Html and you have the whole page. This page can then be modified in any way via string manipulations and reloaded back to webview. – Igor Čordaš Apr 23 '14 at 21:27
1

Since API level 19 there is a handy function evaluateJavascript (String script, ValueCallback<String> resultCallback) that to me makes more sense to use (but I guess the result will be the same). If you just want to run som javascript in the WebView (to modify the DOM for example) the resultCallback can be left empty.

webView = findViewById(R.id.webView);
webView.setWebViewClient(new WebViewClient(){
    @Override
    public void onPageFinished(WebView view, String url) {
        webView.evaluateJavascript(
        "const images = document.getElementsByTagName(\"img\");\n" +
        "for(var i=0; i<images.length; i++){\n" +
        "    if(images[i].alt == \"eBay Logo\"){\n" +
        "        images[i].src = \"my_logo.png\";\n" +
        "    }\n" +
        "}", null);
    }
});
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl("http://ebay.com");
Marcus
  • 11
  • 1
-21
WebView webview = new WebView();

//Maybe need to set to enabled javascript?
webView.getSettings().setJavaScriptEnabled(true);

webview.setWebViewClient(new WebClient());

webview.loadUrl("stackoverflow.com");
DarthJDG
  • 16,511
  • 11
  • 49
  • 56
alphard
  • 1
  • 1