0

How to check in Android WebView if login failed or successful? The login webpage shows following message when login fails due to incorrect username and/or password.

<div id="errorMsgId1427032461760" class="errorMessage"> 

How to check this using JavaScript? (calling next activity works but it always calls next activity. So I want to run this check).

EDIT: I tried by adding JavaScript Interface to webView.loadURL() but it didn't work.

webView.loadUrl("javascript: if(document.body.innerHTML.toString().indexOf('Invalid') > -1){\n" +
                    "         JSInterface.changeActivity() ;");

EDIT 2: How to use this?

if(document.body.innerHTML.toString().indexOf("invalid") > -1){ alert("invalid'"); 

and then call Intent if alert isn't called. (Alert can be any function).

EDIT 3:

I tried with onConsoleMessage, but it doesn't work. Here's code:

webView.setWebChromeClient(new WebChromeClient() {@
Override
public boolean onConsoleMessage(ConsoleMessage cm) {
    String a = cm.toString();
    if (a.equalsIgnoreCase("Success")) {
        Toast.makeText(Login.this, "Login Successful", Toast.LENGTH_SHORT).show();
        Intent intent = new Intent(Login.this, Upload.class);
        Login.this.finish();
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        startActivity(intent);
    }
    if (a.equalsIgnoreCase("Error")) {
        Toast.makeText(Login.this, "Please enter correct credentials", Toast.LENGTH_LONG).show();
    }
    return true;
}
});

and in onPageFinished method as:

webView.setWebViewClient(new WebViewClient() {
        @TargetApi(Build.VERSION_CODES.KITKAT)
        @Override
        public void onPageFinished(WebView view, final String url) {

        webView.loadUrl("javascript: if (document.querySelectorAll('[type=submit]').length) {\n" +
                    "    var x = document.querySelectorAll('[type=submit]');\n" +
                    "    x[0].addEventListener(\"click\", function() {\n" +
                    "        if (document.body.innerHTML.toString().indexOf(\"Invalid\") > -1) console.log(\"Error\");\n" +
                    "        else console.log(\"Success\");\n" +
                    "    });};");
        return true;
        }
    });

    webView.getSettings().setJavaScriptEnabled(true);
    webView.loadUrl("http://192.168.0.101:9999/user");  //Local URL.

I checked above Javascript with alert instead of console.log and it works.

What's error? I can't figure it out.

javaEntu
  • 160
  • 2
  • 14
  • In yout `javascript:` url, you left the figure brackets unclosed-- need to add `}` after `JSInterface.changeActivity();`. Also, you need to have `JSInterface` injected via `WebView.addJavascriptInteface` before you loading the page. – Mikhail Naganov Mar 23 '15 at 12:49
  • Thanks, I'll recheck code and verify it. I'll report soon. – javaEntu Mar 23 '15 at 12:59
  • @MikhailNaganov it didn't work. I injected JSInterface as `JavaScriptInterface JSInterface; JSInterface = new JavaScriptInterface(this); webView.addJavascriptInterface(JSInterface, "JSInterface");` – javaEntu Mar 27 '15 at 10:20

1 Answers1

1

Something like this:

webView.setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient() {
    @Override
    public void onPageFinished(WebView view, String url) {
        if (!<login page url>.equals(url)) return;
        // Available on KitKat and later
        view.evaluateJavascript(
            "document.getElementsByClassName('errorMessage').length",
            new ValueCallback<String>() {
                @Override
                public void onReceiveValue(String errorMessageCount) {
                    if ("0".equals(errorMessageCount)) {
                        // all ok
                    } else {
                        // error message detected
                    }
                }
            }
        );
    }
});

If you also target pre-KitKat releases, then you'll have to use a more complicated way to get a result back from JS, something as described here: How to get return value from javascript in webview of android?

Community
  • 1
  • 1
Mikhail Naganov
  • 6,643
  • 1
  • 26
  • 26
  • Yes, I target pre-KitKat release too, but I'll try this one. – javaEntu Mar 23 '15 at 12:13
  • No, it didn't work. I put my Intent code in **if part, then it fired new Intent ** _without loading login page_ , whereas in **else part, it didn't work at all.** How to use this? `if(document.body.innerHTML.toString().indexOf("invalid") > -1){ alert("invalid'");` and **then call Intent if alert isn't called**. _(Alert can be any function)._ – javaEntu Mar 23 '15 at 12:24
  • @javaEntu: If you load any other pages, besides the login page, the code in `all ok` branch will also most probably fire for them, because they don't have an element with `errorMessage` class. You should add a check, whether `onPageFinished` is fired for the login page. I've added that to my example. – Mikhail Naganov Mar 23 '15 at 12:42
  • Thanks, I'll recheck code and verify it. I'll report soon. – javaEntu Mar 23 '15 at 12:59
  • Not working. Can't understand what's the error. No errors, warnings in Android Studio. I'll try other approach, [that I asked on SO here](http://stackoverflow.com/questions/29240160/android-button-as-webview-click-link-for-logout-or-delete-sessionid/29240235?noredirect=1#comment46708311_29240235) – javaEntu Mar 27 '15 at 10:29