android - how to prevent webview to load when no i

2020-01-29 04:12发布

问题:

I have an Android app which has a webview. When there's no internet connection, webview will display page not available. I want to make this look like an app as much as possible, so I don't want to display this page. I found some useful info online teaching you how to hide or load something else to cover it, but what I really want is to stay at the current page and a little pop up dialog says no connection. Basically, when user clicks on anything inside the webview, check for connection first. if no connection, stay at where it was and pop out a dialog box.

Thanks for the help!!

Edited:

Like I said, I already know how to check internet connection from the samples online. My problem is I don't know how to stop loading the next page. To be clear, when users try to go to the next page, check for internet connection. If no connection, the page will stay at where it was and would not go to the next page. I want users able to see their last loaded page and get informed while webpage content is still there. thanks!

回答1:

I have used the following in my projects:

DetectConnection.Java

import android.content.Context;
import android.net.ConnectivityManager;


public class DetectConnection {             
  public static boolean checkInternetConnection(Context context) {   

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

    return (con_manager.getActiveNetworkInfo() != null
        && con_manager.getActiveNetworkInfo().isAvailable()
        && con_manager.getActiveNetworkInfo().isConnected());
  }
}

Main code:

if (!DetectConnection.checkInternetConnection(this)) {
  Toast.makeText(getApplicationContext(), "No Internet!", Toast.LENGTH_SHORT).show();
} else {      
  wv = (WebView) findViewById(R.id.donate_webView1);
  c = new CustomWebViewClient();
  wv.setWebViewClient(c);
  wv.clearCache(true);
  wv.clearHistory();
  wv.getSettings().setJavaScriptEnabled(true);
  wv.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
  wv.getSettings().setBuiltInZoomControls(true);
  wv.loadUrl("http://www.google.com");
}


// Function to load all URLs in same webview
private class CustomWebViewClient extends WebViewClient {
  public boolean shouldOverrideUrlLoading(WebView view, String url) {
    if (!DetectConnection.checkInternetConnection(this)) {
      Toast.makeText(getApplicationContext(), "No Internet!", Toast.LENGTH_SHORT).show();
    } else {
      view.loadUrl(url);
    }     
    return true;
  }
}

Update the Manifest:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />


回答2:

You can use my CustomWebViewClient it -

  • Shows loading dialog while web page loads
  • Display error messages in case page loading failed
  • In the case of No Internet, it gives user an option to go to setting and enable mobile data.
  • In the case of other type of errors, it allow the user to reload the webpage.

All you need to do is attach it to your webView

webView.setWebViewClient(new CustomWebViewClient ());

CustomWebViewClient class

    /**
     * WebViewClient subclass loads all hyperlinks in the existing WebView
     */
    public class CustomWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            // When user clicks a hyperlink, load in the existing WebView
            view.loadUrl(url);
            return true;
        }

        Dialog loadingDialog = new Dialog(WebViewActivity.this);

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
            webViewPreviousState = PAGE_STARTED;

            if (loadingDialog == null || !loadingDialog.isShowing())
                loadingDialog = ProgressDialog.show(WebViewActivity.this, "",
                        "Loading Please Wait", true, true,
                        new DialogInterface.OnCancelListener() {

                            @Override
                            public void onCancel(DialogInterface dialog) {
                                // do something
                            }
                        });

            loadingDialog.setCancelable(false);
        }


        @RequiresApi(api = Build.VERSION_CODES.M)
        @Override
        public void onReceivedError(WebView view, WebResourceRequest request,
                                    WebResourceError error) {


            if (isConnected()) {
                final Snackbar snackBar = Snackbar.make(rootView, "onReceivedError : " + error.getDescription(), Snackbar.LENGTH_INDEFINITE);
                snackBar.setAction("Reload", new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        webView.loadUrl("javascript:window.location.reload( true )");
                    }
                });
                snackBar.show();
            } else {
                final Snackbar snackBar = Snackbar.make(rootView, "No Internet Connection ", Snackbar.LENGTH_INDEFINITE);
                snackBar.setAction("Enable Data", new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        startActivityForResult(new Intent(Settings.ACTION_WIRELESS_SETTINGS), 0);
                        webView.loadUrl("javascript:window.location.reload( true )");
                        snackBar.dismiss();
                    }
                });
                snackBar.show();
            }

            super.onReceivedError(view, request, error);

        }

        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        @Override
        public void onReceivedHttpError(WebView view,
                                        WebResourceRequest request, WebResourceResponse errorResponse) {

            if (isConnected()) {
                final Snackbar snackBar = Snackbar.make(rootView, "HttpError : " + errorResponse.getReasonPhrase(), Snackbar.LENGTH_INDEFINITE);

                snackBar.setAction("Reload", new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        webView.loadUrl("javascript:window.location.reload( true )");
                    }
                });
                snackBar.show();
            } else {
                final Snackbar snackBar = Snackbar.make(rootView, "No Internet Connection ", Snackbar.LENGTH_INDEFINITE);
                snackBar.setAction("Enable Data", new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        startActivityForResult(new Intent(Settings.ACTION_WIRELESS_SETTINGS), 0);
                        webView.loadUrl("javascript:window.location.reload( true )");
                        snackBar.dismiss();
                    }
                });
                snackBar.show();
            }
            super.onReceivedHttpError(view, request, errorResponse);
        }

        @Override
        public void onPageFinished(WebView view, String url) {

            if (webViewPreviousState == PAGE_STARTED) {

                if (null != loadingDialog) {
                    loadingDialog.dismiss();
                    loadingDialog = null;
                }
            }
        }
    }

Check Connectivity Method

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

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

        if (null != cm) {
            NetworkInfo info = cm.getActiveNetworkInfo();
            return (info != null && info.isConnected());
        }

        return false;

    }


回答3:

        webView.setWebViewClient(new WebViewClient() {
        int errorCode = 0;
        @SuppressWarnings("deprecation")
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            return handleUri(view, url);
        }

        @TargetApi(Build.VERSION_CODES.N)
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
            return handleUri(view, request.getUrl().toString());
        }

        private boolean handleUri(WebView view, final String url) {
            view.loadUrl(url);
            return true;
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            if(errorCode == 0) {
               //CHECK IS PAGE I NEED AND DO STUFF
            } else {
               errorCode = 0;
               //delay and try again
            }
        }

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

        @TargetApi(Build.VERSION_CODES.N)
        @Override
        public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
            handleError(error.getErrorCode());
        }

        private void handleError(int errorCode) {
            this.errorCode = errorCode;
        }
    });


回答4:

You'll want to override the shouldOverrideUrlLoading method of a WebViewClient to catch URL clicks.

To check the Wifi status, you'll want to use the ConnectivityManager

Try this:

WebView mWebView;
NetworkInfo networkInfoWifi = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE).getNetworkInfo(ConnectivityManager.TYPE_WIFI);

mWebView.setWebViewClient(mWebClient);

WebViewClient mWebClient = new WebViewClient(){

    @Override
    public boolean shouldOverrideUrlLoading(WebView  view, String  url){
        return true;
    }

    @Override
    public void onLoadResource(WebView  view, String  url){
        if (networkInfoWifi.isConnected()) {
            //Take action
        }
    }

}

I'd recommend breaking your problem into two smaller steps - Click Interception and Connection Status Checking, and searching for them. This yields plenty of results, and I was able to use these two existing answers to put together the code:

Intercept Webview Click

Check Wifi Connection



回答5:

You can check device is connect to internet through data or wifi by following code

ConnectivityManager manager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo i = manager.getActiveNetworkInfo();
boolean hasConnect = (i!= null && i.isConnected() && i.isAvailable());

if(hasConnect)
                    {
                       // show the webview
                    }
else
 {
    // do what ever you need when when no internet connection
 }

After user go to webview , then if the connect is lost you can capture that event from following code

 webView.setWebViewClient(new Callback());

 public class Callback extends WebViewClient{
    public void onReceivedError(WebView view, int errorCode, String description, String failingUrl){
        Toast.makeText(getApplicationContext(), "Failed loading app!, No Internet Connection found.", Toast.LENGTH_SHORT).show();


    }
}  

following permissions need to give

<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />