Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect if a specific button has been clicked in Android WebView

I am currently working on an android app. This app consists of a WebView and displays a website which I don't own. (F.e. a WebStore)

The app is supposed to recognize/detect when a user clicks a specific button on this website (f.e a "Buy Product" button). If a user clicks such a button, then the app makes a toast pop up.

I know this will be different for every website, however how would I program the click detection in general? I read a few articles about injecting JavaScript etc, however I dont really understand how this is supposed to work. Is there a way to say: If a user clicks on the button with id=buy_button, then show toast?

Thanks for your help!

like image 302
Cédric Portmann Avatar asked Nov 15 '16 21:11

Cédric Portmann


2 Answers

Let me provide you a full example. For your specific website of http://store.nike.com/ch/de_de/pd/mercurial-superfly-v-tech-craft-2-herren-fussballschuh-fur-normalen-rasen/pid-11229711/pgid-11626158

{
    ...

    webview.getSettings().setJavaScriptEnabled(true);
    webview.getSettings().setDomStorageEnabled(true);
    webview.addJavascriptInterface(new MyJavaScriptInterface(this), "ButtonRecognizer");

    webview.setWebViewClient(new WebViewClient() {
        @Override
        public void onPageFinished(WebView view, String url) {
            loadEvent(clickListener());
        }

        private void loadEvent(String javascript){
            webview.loadUrl("javascript:"+javascript);
        }

        private String clickListener(){
            return getButtons()+ "for(var i = 0; i < buttons.length; i++){\n" +
                    "\tbuttons[i].onclick = function(){ console.log('click worked.'); ButtonRecognizer.boundMethod('button clicked'); };\n" +
                    "}";
        }

        private String getButtons(){
            return "var buttons = document.getElementsByClassName('add-to-cart'); console.log(buttons.length + ' buttons');\n";
        }
    });

    webview.loadUrl("http://store.nike.com/ch/de_de/pd/mercurial-superfly-v-tech-cra\u200C\u200Bft-2-herren-fussballschuh-fur-normalen-rasen/pid-11229711/pgid-11626158");

    ...
}


class MyJavaScriptInterface {

    private Context ctx;

    MyJavaScriptInterface(Context ctx) {
        this.ctx = ctx;
    }

    @JavascriptInterface
    public void boundMethod(String html) {
        new AlertDialog.Builder(ctx).setTitle("HTML").setMessage("It worked")
                .setPositiveButton(android.R.string.ok, null).setCancelable(false).create().show();
    }

}

That'll change the onClick for the button to what you need.

For everyone else, it looks like there's either a page-specific issue with getElementById() or an Android issue, but getting the elements by class (getElementsByClassName()) worked as expected. Furthermore, it might be necessary to replace getElementsByClassName() by getElementsByName() such as for example on this website: https://www.digitec.ch/de/s1/product/lexon-flip-wecker-3522142. Where you would put getElementsByName('AddProductToCart')

Info: the \n and the weird combination of strings inside the clickListener method are set like this, because of the IDE. ( ";" are causing problems inside a string).

like image 195
wblaschko Avatar answered Nov 06 '22 17:11

wblaschko


webview.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
   view.loadUrl("javascript:document.getElementById('buy_button').onclick = function(){alert('my message');}");
}
});

This tells your webview that when it is finished loading it needs to execute your custom javascript code. In this case the js code searches the page for element with id "buy button" and sets the onclick handler to alert your message.

If you specifically need to toast then you will need to setup a javascript interface and then call a method on their instead. make sense?

like image 32
Steven Mark Ford Avatar answered Nov 06 '22 17:11

Steven Mark Ford