109
public void onCreate(Bundle savedInstance)
{       
    super.onCreate(savedInstance);
    setContentView(R.layout.show_voucher);
    webView=(WebView)findViewById(R.id.webview);
    webView.getSettings().setJavaScriptEnabled(true);
    webView.getSettings().setBuiltInZoomControls(true);
    String url ="https://www.paymeon.com/Vouchers/?v=%C80%8D%B1x%D9%CFqh%FA%84%C35%0A%1F%CE&iv=%25%EE%BEi%F4%DAT%E1"
    //webView.loadUrl(url); // Not Working... Showing blank
    webView.loadUrl("http://www.yahoo.com"); // its working    
}

When I try to load a URL in the WebBView it only shows a blank screen. If I load Google.com or yahoo.com it's working fine.

Timo Salomäki
  • 7,099
  • 3
  • 25
  • 40
sumit
  • 1,091
  • 2
  • 8
  • 3
  • 1
    it's working i checked now. check again if not working after that add this with your code webView.getSettings().setUseWideViewPort(true); webView.getSettings().setLoadWithOverviewMode(true); – ilango j Sep 14 '11 at 12:22

16 Answers16

172

Please visit this link:

Add this overriding method to your WebViewClient implementation. You'll need to compile it with Android SDK 2.2 (API level 8) or later. The method appears in the public SDK as of 2.2 (API level 8) but we've tested it on devices running 2.1, 1.6 and 1.5 and it works on those devices too (so obviously the behaviour has been there all along).

 @Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
    handler.proceed(); // Ignore SSL certificate errors
}

this will help you.

fargath
  • 7,844
  • 6
  • 24
  • 36
  • 3
    The last entry in the discussion worked great. Thanks very much. – Bill Lahti Dec 20 '11 at 20:32
  • 68
    **Security warning**: Note that doing so completely defeats the purpose of having SSL in the first place. – ereOn Jan 16 '14 at 14:21
  • @fargath I want to remove the SSLV3 protocol from the webview supported protocols as this protocol is disabled from server side they are using TLS 2.0 . How can do this ? – KK_07k11A0585 Aug 04 '15 at 07:15
  • 9
    Please don't do this. It's insecure and not allowed in the Play Store. – Antimony Nov 02 '15 at 17:42
  • 41
    Google is now sending emails to whoever implements the solution above: `Your app(s) listed at the end of this email have an unsafe implementation of the WebViewClient.onReceivedSslError handler. Specifically, the implementation ignores all SSL certificate validation errors, making your app vulnerable to man-in-the-middle attacks.` `Apps with vulnerabilities that expose users to risk of compromise may be considered Dangerous Products in violation of the Content Policy and section 4.4 of the Developer Distribution Agreement.` – Gustavo Pagani Dec 17 '15 at 10:07
  • 6
    Any one know how to solve google Security warning, if yes please let me know because i also facing this problem. – Pratik Tank Feb 22 '16 at 13:08
  • 1
    You need to invoke handler.proceed() whenever the certificate presented by the server meets your expectations, otherwise handler.cancel() . Otherwise google will raise security warning like above . – Ratul Ghosh Apr 22 '16 at 08:37
  • 3
    ereOn: I disagree. This comment is useful. It solves problems with self certified SSL certificates. I'm not uploading my app to the google store either. – CMP Oct 14 '16 at 15:48
  • 1
    FYI, app will be rejected on play store while making it live. – B.shruti Jul 26 '19 at 06:39
  • you could probably just easily add an if case to make sure it is the right self certified SSL certificate and if you want you can make this anyway only in the WebView for this one Website you are showing. or am I missing something fundamentale? – Chagai Friedlander May 07 '20 at 14:29
53

Per correct answer by fargth, follows is a small code sample that might help.

First, create a class that extends WebViewClient and which is set to ignore SSL errors:

// SSL Error Tolerant Web View Client
private class SSLTolerentWebViewClient extends WebViewClient {

            @Override
            public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
                handler.proceed(); // Ignore SSL certificate errors
            }

}

Then with your web view object (initiated in the OnCreate() method), set its web view client to be an instance of the override class:

 mWebView.setWebViewClient(
                new SSLTolerentWebViewClient()
        );
robnick
  • 1,720
  • 17
  • 27
45

To properly handle SSL certificate validation and avoid application rejection from Google according new Security Policy, Change your code to invoke SslErrorHandler.proceed() whenever the certificate presented by the server meets your expectations, and invoke SslErrorHandler.cancel() otherwise.

For example, I add an alert dialog to make user have confirmed and seems Google no longer shows warning.

    @Override
    public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
    final AlertDialog.Builder builder = new AlertDialog.Builder(this);
    String message = "SSL Certificate error.";
        switch (error.getPrimaryError()) {
            case SslError.SSL_UNTRUSTED:
                message = "The certificate authority is not trusted.";
                break;
            case SslError.SSL_EXPIRED:
                message = "The certificate has expired.";
                break;
            case SslError.SSL_IDMISMATCH:
                message = "The certificate Hostname mismatch.";
                break;
            case SslError.SSL_NOTYETVALID:
                message = "The certificate is not yet valid.";
                break;
        }
        message += " Do you want to continue anyway?";

        builder.setTitle("SSL Certificate Error");
        builder.setMessage(message);
    builder.setPositiveButton("continue", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            handler.proceed();
        }
    });
    builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            handler.cancel();
        }
    });
    final AlertDialog dialog = builder.create();
    dialog.show();
}

After this changes it will not show warning.

Anant Shah
  • 3,744
  • 1
  • 35
  • 48
  • 1
    what will happen if I removed onReceivedSslError block from the implementation? – Vivek Sinha Jul 16 '16 at 08:28
  • 1
    @VivekSinha it will call handler.cancel(); by default. – Anant Shah Jul 16 '16 at 11:27
  • 3
    but Google still rejected my app saying same reason. Why? – Vivek Sinha Jul 18 '16 at 08:28
  • 1
    @VivekSinha found any solution regarding to app launch in play store ? – Kesha Oct 07 '17 at 06:46
  • 2
    I implemented onReceivedSslError callback as suggested. App was published successfully afterwards. – Vivek Sinha Oct 07 '17 at 11:03
  • "An app may be flagged if it does not contain sufficient checks for certificate validity; for instance, just checking the return value of getPrimaryError is not sufficient to establish the validity of the certificate." [source](https://support.google.com/faqs/answer/7071387?hl=en) – Yoda066 Jun 03 '20 at 15:55
13

override onReceivedSslError and remove

super.onReceivedSslError(view, handler, error)

And to solve Google security:

setDomStorageEnabled(true);

Full code is:

webView.enableJavaScript();
webView.getSettings().setDomStorageEnabled(true); // Add this
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webView.setWebViewClient(new WebViewClient(){
        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
            // DO NOT CALL SUPER METHOD
            super.onReceivedSslError(view, handler, error);
        }
    });
Alp Altunel
  • 3,324
  • 1
  • 26
  • 27
FarshidABZ
  • 3,860
  • 4
  • 32
  • 63
11

Remove the below code it will work

 super.onReceivedSslError(view, handler, error);
King of Masses
  • 18,405
  • 4
  • 60
  • 77
  • Great, it worked for me. Can you please explain how it worked? – Arth Tilva Jun 06 '16 at 05:50
  • 3
    @ArthTilva from the google docs: "default behaviour is to cancel the load". By calling super you are calling that default behaviour before it can reach the rest of the method. https://developer.android.com/reference/android/webkit/WebViewClient.html#onReceivedSslError – Josh Laird Oct 15 '16 at 12:31
8

Copy and paste your code line bro , it will work trust me :) i am thinking ,you get a ssl error. İf you use override onReceivedSslError method and remove super it's super method. Just write handler.proceed() ,error will solve.

    webView.setWebChromeClient(new WebChromeClient() {
        public void onProgressChanged(WebView view, int progress) {

            activity.setTitle("Loading...");
            activity.setProgress(progress * 100);

            if (progress == 100)
                activity.setTitle(getResources().getString(R.string.app_name));
        }
    });

    webView.setWebViewClient(new WebViewClient() {
        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            Log.d("Failure Url :" , failingUrl);
        }

        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
            Log.d("Ssl Error:",handler.toString() + "error:" +  error);
            handler.proceed();
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }
    });
    webView.getSettings().setJavaScriptEnabled(true);
    webView.getSettings().setLoadWithOverviewMode(true);
    webView.getSettings().setUseWideViewPort(true);
    webView.getSettings().setDomStorageEnabled(true);
    webView.loadUrl(Constant.VIRTUALPOS_URL + "token=" + Preference.getInstance(getContext()).getToken() + "&dealer=" + Preference.getInstance(getContext()).getDealerCode());
ozanurkan
  • 399
  • 4
  • 13
6

I followed the answers above but still it seems not to be working for me below code did a trick for me when integrating payment gatways which are usually https requests :

public class MainActivity extends Activity {

    WebView webView;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        webView = (WebView) findViewById(R.id.webView1);
        WebSettings settings = webView.getSettings();
        settings.setJavaScriptEnabled(true);
        settings.setDomStorageEnabled(true);
        webView.setWebViewClient(new MyWebViewClient());
        String postData = "amount=1000&firstname=mtetno&email=mttee@gmail.com&phone=2145635784&productinfo=android&surl=success.php"
                + "&furl=failure.php&lastname=qwerty&curl=dsdsd.com&address1=dsdsds&address2=dfdfd&city=dsdsds&state=dfdfdfd&"
                + "country=fdfdf&zipcode=123456&udf1=dsdsds&udf2=fsdfdsf&udf3=jhghjg&udf4=fdfd&udf5=fdfdf&pg=dfdf";
        webView.postUrl(
                "http://host/payment.php",
                EncodingUtils.getBytes(postData, "BASE64"));

    }

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

        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler,
                SslError error) {
            handler.proceed();
        }
    }
}

Above code is doing a post request in webview and redirecting to payment gateway.

Setting settings.setDomStorageEnabled(true); did a trick for me Hope this helps .

HimalayanCoder
  • 9,630
  • 6
  • 59
  • 60
KOTIOS
  • 11,177
  • 3
  • 39
  • 66
  • 2
    This solution COMPLETELY disables certificate validation, leaving you open for man-in-the-middle attacks. This is something you should never do, ESPECIALLY for payment gateways. – Dirbaio Apr 01 '17 at 20:08
  • For me initially the webview was not loading the content, but just the background image of the page. After I just added `webview.getSettings.setDomStorageEnabled(true);` it magically worked. Maybe the webpage is using some kind of HTML 5 API, so enabling DomStorage worked for me. – Ishant Sagar Jul 03 '17 at 16:22
  • handler.proceed() bypassing SSL – John Ruban Singh Oct 24 '19 at 21:15
  • what is Encodingutil.getbyte – Akash kumar May 20 '20 at 09:40
6

To handle SSL urls the method onReceivedSslError() from the WebViewClient class, This is an example:

 webview.setWebViewClient(new WebViewClient() {
              ...
              ...
              ...

            @Override
            public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
                String message = "SSL Certificate error.";
                switch (error.getPrimaryError()) {
                    case SslError.SSL_UNTRUSTED:
                        message = "The certificate authority is not trusted.";
                        break;
                    case SslError.SSL_EXPIRED:
                        message = "The certificate has expired.";
                        break;
                    case SslError.SSL_IDMISMATCH:
                        message = "The certificate Hostname mismatch.";
                        break;
                    case SslError.SSL_NOTYETVALID:
                        message = "The certificate is not yet valid.";
                        break;
                }
                message += "\"SSL Certificate Error\" Do you want to continue anyway?.. YES";

                handler.proceed();
            }

        });

You can check my complete example here: https://github.com/Jorgesys/Android-WebView-Logging

enter image description here

Jorgesys
  • 124,308
  • 23
  • 334
  • 268
6

To solve Google security, do this:

Lines to the top:

import android.webkit.SslErrorHandler;
import android.net.http.SslError;

Code:

class SSLTolerentWebViewClient extends WebViewClient {
    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
        if (error.toString() == "piglet")
            handler.cancel();
        else
            handler.proceed(); // Ignore SSL certificate errors
    }
}
Gediminas Šukys
  • 7,101
  • 7
  • 46
  • 59
Ronen
  • 1,225
  • 13
  • 10
4

In case you want to use the APK outside the Google Play Store, e.g., private a solution like the following will probably work:

    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
        /*...*/
        handler.proceed();
    }

In case you want to add an additional optional layer of security, you can try to make use of certificate pinning. IMHO this is not necessary for private or internal usage tough.

If you plan to publish the app on the Google Play Store, then you should avoid @Override onReceivedSslError(...){...}. Especially making use of handler.proceed(). Google will find this code snippet and will reject your app for sure since the solution with handler.proceed() will suppress all kinds of built-in security mechanisms.

And just because of the fact that browsers do not complain about your https connection, it does not mean that the SSL certificate itself is trusted at all!

In my case, the SSL certificate chain was broken. You can quickly test such issues with SSL Checker or more intermediate with SSLLabs. But please do not ask me how this can happen. I have absolutely no clue.

Anyway, after reinstalling the SSL certificate, all errors regarding the "untrusted SSL certificate in WebView whatsoever" disappeared finally. I also removed the @Override for onReceivedSslError(...) and got rid of handler.proceed(), and é voila my app was not rejected by Google Play Store (again).

Dharman
  • 30,962
  • 25
  • 85
  • 135
Manuel
  • 51
  • 3
2

Recommended approach will be

1.Don't call super method(Remove super call from overridden method)

2.Google recommend to call SslErrorHandler.cancel() method if any error comes

3.Don't Prompt dialog to expose SSL errors

Whats the best solution?? Remove this override method

@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler,SslError error) {

}
John Ruban Singh
  • 1,284
  • 14
  • 19
  • Are you asking for a solution or suggesting one? – Dharman Oct 24 '19 at 20:13
  • I am suggesting this approach – John Ruban Singh Oct 24 '19 at 21:02
  • @JohnRubanSingh Hi John, I've loading a JS file from assets and once file loaded with onPageFinished I'm calling a function inside JS. So, overriding onReceivedSslError() is neccessary as I'm using webview.setWebViewClient(new ....) ? – Shivam Sharma Mar 25 '20 at 07:07
  • This code rejecting my APK.Even since 9 months this code is not causes rejection but suddenly facing rejections r8 now. switch (error.getPrimaryError()) { case SslError.SSL_UNTRUSTED: handler.proceed(); break; case SslError.SSL_EXPIRED: case SslError.SSL_IDMISMATCH: case SslError.SSL_NOTYETVALID: case SslError.SSL_DATE_INVALID: case SslError.SSL_INVALID: default: handler.cancel(); break; } – Shivam Sharma Mar 25 '20 at 07:14
  • @JohnRubanSingh please help me. We can join on slack. – Shivam Sharma Mar 25 '20 at 08:41
2

My website is a subdomain which is developed on angular 8 which is also using localstorage and cookies. website showed after setting the below line, along with other solutions mentioned above.

webSettings.setDomStorageEnabled(true);
jkr
  • 630
  • 1
  • 11
  • 24
2

add android:usesCleartextTraffic="true" in application tag in manifest all will be ok . this works for me.

zim tech
  • 21
  • 1
1

Use this line webview.getSettings().setDomStorageEnabled(true) in your java code

WebView webView = (WebView) findViewById(R.id.webview);    
webView.getSettings().setDomStorageEnabled(true);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.loadUrl(yourUrl);
Abdul Basit Rishi
  • 2,268
  • 24
  • 30
0

Setting thoses two properties were enough to make it work for me, and doesn't expose to security issues :

 WebSettings settings = webView.getSettings();
    settings.setJavaScriptEnabled(true);
    settings.setDomStorageEnabled(true);
GreuM
  • 155
  • 11
0

check your User Agent , if it too long your should get this error