简体   繁体   中英

Android WebView not loading an HTTPS URL

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.

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.

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()
        );

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.

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

删除下面的代码它将起作用

 super.onReceivedSslError(view, handler, error);

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());

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 .

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

在此处输入图片说明

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
    }
}

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) {

}

In case you want to use the APK outside the Google Play Store, eg, 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).

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

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM