Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 362
sumit Avatar asked Sep 14 '11 12:09

sumit


People also ask

How do I add a website to my Android WebView?

Modify src/MainActivity. java file to add WebView code. Run the application and choose a running android device and install the application on it and verify the results. Following is the content of the modified main activity file src/MainActivity.

Why is my WebView not working?

You might often face issues in updating the chrome and Android System Webview. To fix this problem, you can reboot your device, check your internet connection, stop auto-updating all apps, clear Google Playstore cache, and storage, leave the beta testing program, and manually update Android WebView app from Playstore.

How do I open a link in WebView?

Within the shouldOverrideUrlLoading() method simply get the URL from the request and pass into the Intent. See the full example.

Is Android WebView deprecated?

This interface was deprecated in API level 12. This interface is now obsolete.

How to handle page navigation in Android WebView?

Handling page navigation. When the user clicks a link from a web page in your WebView, the default behavior is for Android to launch an app that handles URLs. Usually, the default web browser opens and loads the destination URL. However, you can override this behavior for your WebView, so links open within your WebView.

How do I override the URL loading of a WebView?

myWebView.webViewClient = MyWebViewClient() Now when the user clicks a link, the system calls shouldOverrideUrlLoading (), which checks whether the URL host matches a specific domain (as defined above). If it does match, then the method returns false in order to not override the URL loading (it allows the WebView to load the URL as usual).

What happens when you click on a link in WebView?

When the user clicks a link from a web page in your WebView, the default behavior is for Android to launch an app that handles URLs. Usually, the default web browser opens and loads the destination URL. However, you can override this behavior for your WebView, so links open within your WebView.

How do I use WebView in an Android app?

A common scenario in which using WebView is helpful is when you want to provide information in your app that you might need to update, such as an end-user agreement or a user guide. Within your Android app, you can create an Activity that contains a WebView, then use that to display your document that's hosted online.


14 Answers

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.

like image 192
fargath Avatar answered Nov 11 '22 00:11

fargath


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()         ); 
like image 41
robnick Avatar answered Nov 11 '22 00:11

robnick


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.

like image 27
Anant Shah Avatar answered Nov 11 '22 00:11

Anant Shah


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);
        }
    });
like image 42
FarshidABZ Avatar answered Nov 11 '22 00:11

FarshidABZ


Remove the below code it will work

 super.onReceivedSslError(view, handler, error);
like image 26
King of Masses Avatar answered Nov 11 '22 00:11

King of Masses


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());
like image 28
ozanurkan Avatar answered Nov 11 '22 00:11

ozanurkan


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 protected]&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 .

like image 32
KOTIOS Avatar answered Nov 11 '22 02:11

KOTIOS


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

like image 39
Jorgesys Avatar answered Nov 11 '22 02:11

Jorgesys


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
    }
}
like image 27
Ronen Avatar answered Nov 11 '22 01:11

Ronen


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

}
like image 40
John Ruban Singh Avatar answered Nov 11 '22 01:11

John Ruban Singh


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

like image 30
Manuel Avatar answered Nov 11 '22 02:11

Manuel


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);
like image 35
Abdul Basit Rishi Avatar answered Nov 11 '22 02:11

Abdul Basit Rishi


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);
like image 32
jkr Avatar answered Nov 11 '22 01:11

jkr


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

like image 34
zim tech Avatar answered Nov 11 '22 02:11

zim tech