51

I'd like to show an error message when there is an error loading a webview page (No connection). This is what I have so far, without the error handling code:

public class TrackerPage extends Activity {

    // @Override
    private WebView webview;
    private ProgressDialog progressDialog;

    private boolean error;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Get rid of the android title bar
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        // Set the XML layout
        setContentView(R.layout.tracker_page);

        // Bundle objectbundle = this.getIntent().getExtras();
        webview = (WebView) findViewById(R.id.tracker);

        final Activity activity = this;

        // Enable JavaScript and lets the browser go back
        webview.getSettings().setJavaScriptEnabled(true);
        webview.canGoBack();

        webview.setWebViewClient(new WebViewClient() {
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }

            public void onLoadResource(WebView view, String url) {
                // Check to see if there is a progress dialog
                if (progressDialog == null) {
                    // If no progress dialog, make one and set message
                    progressDialog = new ProgressDialog(activity);
                    progressDialog.setMessage("Loading please wait...");
                    progressDialog.show();

                    // Hide the webview while loading
                    webview.setEnabled(false);
                }
            }

            public void onPageFinished(WebView view, String url) {
                // Page is done loading;
                // hide the progress dialog and show the webview
                if (progressDialog.isShowing()) {
                    progressDialog.dismiss();
                    progressDialog = null;
                    webview.setEnabled(true);
                }
            }

        });

        // The URL that webview is loading
        webview.loadUrl("http://url.org/");
    }
}

How would I do this?

Kyle Falconer
  • 8,302
  • 6
  • 48
  • 68
HighLife
  • 4,218
  • 7
  • 40
  • 56

6 Answers6

47

All answer above are deprecated. You should use this code after on Page finished

 @Override
    public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error){
           //Your code to do
        Toast.makeText(getActivity(), "Your Internet Connection May not be active Or " + error.getDescription(), Toast.LENGTH_LONG).show();
    }
Maxim Mazurok
  • 3,856
  • 2
  • 22
  • 37
Harsh Mittal
  • 2,868
  • 1
  • 16
  • 21
  • 3
    How to use the above if your project targets API level < 23? – Michael Nov 15 '16 at 03:32
  • @Michael, there's another method with different parameters that was introduce in API level 1 – onReceivedError(WebView, int, String, String) – christiandeange Dec 13 '16 at 22:47
  • 4
    If there is no internet, all I see is "webpage not found", and none of those callbacks are called. How come? Also, is it better to use the newer API of onReceivedError? According to the docs, it is called for every component on the page. How can I check it when it's just for the whole page? – android developer Mar 23 '17 at 15:55
  • Does one have to override both in order to cover both possibilities of api levels? – MDjava Nov 08 '18 at 05:24
  • @MDjava yes you do have to override both if you target API below and above 23. – Oleksandr Kruk Mar 13 '19 at 11:17
30

You're most of the way there... Just implement onReceivedError and handle the errors that you want.

kabuko
  • 36,028
  • 10
  • 80
  • 93
19

Add this after onpagefinished :

    public void onReceivedError(WebView view, int errorCod,String description, String failingUrl) {
            Toast.makeText(Webform.this, "Your Internet Connection May not be active Or " + description , Toast.LENGTH_LONG).show();
        }

Don't forget to import android.widget.Toast;

Yahyaotaif
  • 1,943
  • 1
  • 15
  • 17
12

Updated answer as per API 23 Marshmallow

WebViewClient Errors Handling

    /*
     * Added in API level 23 replacing :-
     *
     * onReceivedError(WebView view, int errorCode, String description, String failingUrl) 
    */
    @Override
    public void onReceivedError(WebView view, WebResourceRequest request,
            WebResourceError error) {

        Toast.makeText(getActivity(),
                "WebView Error" + error.getDescription(),
                Toast.LENGTH_SHORT).show();

        super.onReceivedError(view, request, error);

    }

    /*
      Added in API level 23
    */
    @Override
    public void onReceivedHttpError(WebView view,
            WebResourceRequest request, WebResourceResponse errorResponse) {

        Toast.makeText(getActivity(),
                "WebView Error" + errorResponse.getReasonPhrase(),
                Toast.LENGTH_SHORT).show();


        super.onReceivedHttpError(view, request, errorResponse);
    }

Network Error Handling

        webView.loadUrl(urlToLoad);

        if (!isConnected(getActivity())) {
            Toast.makeText(getActivity(), "You are offline ", Toast.LENGTH_SHORT).show();

        }

     /**
     * Check if there is any connectivity
     * 
     * @param context
     * @return is Device Connected
     */
    public static boolean isConnected(Context context) {

        ConnectivityManager cm = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);

        if (null != cm) {
            NetworkInfo info = cm.getActiveNetworkInfo();

            return (info != null && info.isConnected());
        }
        return false;
    }
Hitesh Sahu
  • 41,955
  • 17
  • 205
  • 154
8
public class WebClient extends WebViewClient {

    @Override
    @TargetApi(Build.VERSION_CODES.M)
    public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
        super.onReceivedError(view, request, error);
        final Uri uri = request.getUrl();
        handleError(view, error.getErrorCode(), error.getDescription().toString(), uri);
    }

    @SuppressWarnings("deprecation")
    public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
        super.onReceivedError(view, errorCode, description, failingUrl);
        final Uri uri = Uri.parse(failingUrl);
        handleError(view, errorCode, description, uri);
    }

    private void handleError(WebView view, int errorCode, String description, final Uri uri) {
        final String host = uri.getHost();// e.g. "google.com"
        final String scheme = uri.getScheme();// e.g. "https"
        // TODO: logic
    }
}
Vlad
  • 7,997
  • 3
  • 56
  • 43
7

in onReceivedError methode handle like below

@SuppressWarnings("deprecation")
@Override
public void onReceivedError(WebView view, int errorCode, String description,        String failingUrl) {
    handleError(errorCode,view);
}

@TargetApi(android.os.Build.VERSION_CODES.M)
@Override
public void onReceivedError(WebView view, WebResourceRequest req, WebResourceError rerr) {
    // Redirect to deprecated method, so you can use it in all SDK versions
    onReceivedError(view, rerr.getErrorCode(),rerr.getDescription().toString(),req.getUrl().toString());

}

HandleError methode below

public static void handleError(int errorCode, WebView view) {
    
    String message = null;
    if (errorCode == WebViewClient.ERROR_AUTHENTICATION) {
        message = "User authentication failed on server";
    } else if (errorCode == WebViewClient.ERROR_TIMEOUT) {
        message = "The server is taking too much time to communicate. Try again later.";
    } else if (errorCode == WebViewClient.ERROR_TOO_MANY_REQUESTS) {
        message = "Too many requests during this load";
    } else if (errorCode == WebViewClient.ERROR_UNKNOWN) {
        message = "Generic error";
    } else if (errorCode == WebViewClient.ERROR_BAD_URL) {
        message = "Check entered URL..";
    } else if (errorCode == WebViewClient.ERROR_CONNECT) {
        message = "Failed to connect to the server";
    } else if (errorCode == WebViewClient.ERROR_FAILED_SSL_HANDSHAKE) {
        message = "Failed to perform SSL handshake";
    } else if (errorCode == WebViewClient.ERROR_HOST_LOOKUP) {
        message = "Server or proxy hostname lookup failed";
    } else if (errorCode == WebViewClient.ERROR_PROXY_AUTHENTICATION) {
        message = "User authentication failed on proxy";
    } else if (errorCode == WebViewClient.ERROR_REDIRECT_LOOP) {
        message = "Too many redirects";
    } else if (errorCode == WebViewClient.ERROR_UNSUPPORTED_AUTH_SCHEME) {
        message = "Unsupported authentication scheme (not basic or digest)";
    } else if (errorCode == WebViewClient.ERROR_UNSUPPORTED_SCHEME) {
        message = "unsupported scheme";
    } else if (errorCode == WebViewClient.ERROR_FILE) {
        message = "Generic file error";
    } else if (errorCode == WebViewClient.ERROR_FILE_NOT_FOUND) {
        message = "File not found";
    } else if (errorCode == WebViewClient.ERROR_IO) {
        message = "The server failed to communicate. Try again later.";
    }
    if (message != null) {
        Toast.makeText(getActivity(), "" + message, Toast.LENGTH_LONG).show();
    }
}
Naveed Ahmad
  • 6,627
  • 2
  • 58
  • 83
Sumit Bandekar
  • 410
  • 5
  • 10