user7962849
user7962849

Reputation:

How To Add Retry Button in Custom error Page Of Android Webview?

I have Created Android Webview For The website. I have Created custom error page when internet is not connected. The file is loading fine. if internet is not connected error page is loading. Is there any way to add retry button in custom error page so that once internet is connected and if user clicks the retry button and then load the webview again? Now I have to exit app and then again i have to again open the app once internet is connected. Rather than exiting app, once internet is connected i want have retry button on custom error page so that without exiting app webview will be loaded. Or Is it possible to load webview automatically once internet is connected?

MainActivity.java is

package com.flyingcolorz.flyingcolorz;

import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.app.Activity;
import android.view.KeyEvent;
import android.content.DialogInterface;
import android.app.AlertDialog;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.graphics.Bitmap;
import android.view.View;
import android.widget.ProgressBar;
import android.webkit.WebResourceRequest;
import android.content.Intent;
import android.net.Uri;

public class MainActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    String url = "https://google.com/";
    setContentView(R.layout.activity_main);
    final WebView myWebView = (WebView) findViewById(R.id.webview);
    WebSettings webSettings = myWebView.getSettings();
    webSettings.setJavaScriptEnabled(true);
    myWebView.loadUrl(url);
    //myWebView.setWebViewClient(new WebViewClient());
    // Get Connectivity Manager class object from Systems Service
    //ConnectivityManager cm = (ConnectivityManager)  getSystemService(Context.CONNECTIVITY_SERVICE);
    // Get Network Info from connectivity Manager
    //NetworkInfo networkInfo = cm.getActiveNetworkInfo();
    // if no network is available networkInfo will be null
    // otherwise check if we are connected
    // if (networkInfo == null) {
    myWebView.setWebViewClient(new WebViewClient() {
      @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
        myWebView.loadUrl("file:///android_asset/error.html");
      }
    });
    // }
  }
  //goto previous page
  @Override
  public boolean onKeyDown(int keyCode, KeyEvent event) {
    WebView myWebView = (WebView) findViewById(R.id.webview);
    if (event.getAction() == KeyEvent.ACTION_DOWN) {
      switch (keyCode) {
        case KeyEvent.KEYCODE_BACK:
          if (myWebView.canGoBack()) {
            myWebView.goBack();
          } else {
            //finish();
            new AlertDialog.Builder(this)
              .setIcon(android.R.drawable.ic_dialog_alert)
              .setTitle("Exit")
              .setMessage("Are you sure you want to exit?")
              .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                  finish();
                }

              })
              .setNegativeButton("No", null)
              .show();
          }
          return true;
      }
    }
    return super.onKeyDown(keyCode, event);
  }
}

Upvotes: 0

Views: 2262

Answers (3)

Gopal Meena
Gopal Meena

Reputation: 427

A medical student is here, trying to solve your problem. Just add a button in your error page (error.html).

<a href="https://www.google.com/" ><button>RETRY</button></a>

bye! It's time to see a patient.

Upvotes: 0

Hrishikesh Kokate
Hrishikesh Kokate

Reputation: 1225

You might have to add some connectivity trigger that will reload to the original URL automatically once it detects that the connectivity is back. However, I don't know if it's even possible or how to do that.

I had the exact same issue. Here's how I tackled it (I didn't want Swipe to Refresh):

I created a seperate activity for the error page (say ErrorActivity) and loaded the error.html page like you'd load a normal webview.

So, I changed my onReceivedError to this:

    @Override
    public void onReceivedError(WebView webview, int i, String s, String s1)
    {
        WebView.setVisibility(View.GONE);
        Intent intent = new Intent(MainActivity.this, ErrorActivity.class);
        startActivity(intent);
        finish();
    }

Basically, this code is detecting that some error has been received, then it is hiding the original WebView and launching the ErrorActivity using an Intent, and finishing the MainActivity.

The ErrorActivity is then having my error.html page which tells users to reload the page from a menu button.

Now, to create the ErrorActivity we'll need to define it in AndroidManifest.xml, create a layout file for it and then load the WebView.

If you don't already have a menu, you'll have to create a menu folder inside res. An example menu.xml file for this case:

<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">

            <item
                android:id="@+id/refresh"
                android:icon="@drawable/ic_refresh_black_24dp"
                android:orderInCategory="1"
                app:showAsAction="always"
                tools:ignore="AlwaysShowAction"
                android:title="@string/refresh"/>

</menu>

In ErrorActivity.java, outside your onCreate, add this:

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    MenuInflater menuInflater = getMenuInflater();
    menuInflater.inflate(R.menu.menu, menu);
    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item)
{
    switch (item.getItemId())
    {
        case R.id.refresh:
            Intent intent = new Intent(ErrorActivity.this, MainActivity.class);
            startActivity(intent);
            finish();
            break;
    }
    return super.onOptionsItemSelected(item);
}

Basically, as soon as you press on Refresh, your app will try to load MainActivity. If there still are some internet connectivity issues, your MainActivity's WebView will again receive an error and that will again load ErrorActivity. So far, this has worked flawlessly for me.

This should do it.

Be sure to update the id, etc. if you're gonna change this code to match your needs.

Upvotes: 0

karan
karan

Reputation: 8843

You can do something like this for as a solution.

Add your webview with swiperefresh layout.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.vvhvb.hesselfeenstra.vvheerenveenseboys.MainActivity"
tools:showIn="@layout/activity_main">

<android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/swipeContainer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <WebView
        android:id="@+id/webView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true" />

</android.support.v4.widget.NestedScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>

And show your error message as "Error Occoured! Swipe from top to retry."

Now when user refreshes load default url that you want into your webview.

mySwipeRefreshLayout.setOnRefreshListener(
    new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            webview.loadUrl(url);
        }
      }
    );

Upvotes: 1

Related Questions