How to go back to previous page if back button is pressed in WebView?

AndroidAndroid Webview

Android Problem Overview


I have an app in which I have a WebView where I display some websites. It works, clicking a link in the webpage goes to the next page in the website inside my app. But when I click the phone's back button, it takes me straight into my app. I want to go back to the previous page in the website instead. How can I do this?

Here is the code sample I'm using:

public class Webdisplay extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
    
        this.getWindow().requestFeature(Window.FEATURE_PROGRESS);
        setContentView(R.layout.webdisplay);
    
        getWindow().setFeatureInt(Window.FEATURE_PROGRESS,
                Window.PROGRESS_VISIBILITY_ON); 

        Toast loadingmess = Toast.makeText(this,
                "Cargando El Diario de Hoy", Toast.LENGTH_SHORT);
        loadingmess.show();
 
        WebView myWebView;
	 
        myWebView = (WebView) findViewById(R.id.webview);
        myWebView.getSettings().setJavaScriptEnabled(true);
        myWebView.loadUrl("http://www.elsalvador.com");
        myWebView.setWebViewClient(new WebViewClient());
        myWebView.setInitialScale(1);
        myWebView.getSettings().setBuiltInZoomControls(true);
        myWebView.getSettings().setUseWideViewPort(true);
	   
        final Activity MyActivity = this;
        myWebView.setWebChromeClient(new WebChromeClient() 
        {
            public void onProgressChanged(WebView view, int progress)   
            {
                MyActivity.setTitle("Loading...");
                MyActivity.setProgress(progress * 100); 
         
                if(progress == 100)
                    MyActivity.setTitle(R.string.app_name);
            }
        });
    }
}

Android Solutions


Solution 1 - Android

I use something like this in my activities with WebViews:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (event.getAction() == KeyEvent.ACTION_DOWN) {
        switch (keyCode) {
            case KeyEvent.KEYCODE_BACK:
                if (mWebView.canGoBack()) {
                    mWebView.goBack();
                } else {
                    finish();
                }
                return true;
        }

    }
    return super.onKeyDown(keyCode, event);
}

Edit:

For this code to work, you need to add a field to the Activity containing the WebView:

private WebView mWebView;

Initialize it in the onCreate() method and you should be good to go.

mWebView = (WebView) findViewById(R.id.webView);

Solution 2 - Android

If using Android 2.2 and above (which is most devices now), the following code will get you what you want.

@Override
public void onBackPressed()	{
    if (webView.canGoBack()) {
        webView.goBack();
    } else {
    	super.onBackPressed();
    }
}

Solution 3 - Android

This is my solution. It works also in Fragment.

webView.setOnKeyListener(new OnKeyListener() {
	@Override
	public boolean onKey(View v, int keyCode, KeyEvent event) {
		if (event.getAction() == KeyEvent.ACTION_DOWN) {
			WebView webView = (WebView) v;
			
			switch(keyCode) {
				case KeyEvent.KEYCODE_BACK:
					if (webView.canGoBack()) {
						webView.goBack();
						return true;
					}
					break;
			}
		}
		
		return false;
	}
});

Solution 4 - Android

Full reference for next button and progress bar : put back and next button in webview

If you want to go to back page when click on phone's back button, use this:

@Override
public void onBackPressed() {
    if (webView.canGoBack()) {
        webView.goBack();
    } else {
        super.onBackPressed();
    }
} 

You can also create custom back button like this:

btnback.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            if (wv.canGoBack()) {
                wv.goBack();
            }
        }
    }); 

Solution 5 - Android

Focusing should also be checked in onBackPressed

    @Override
    public void onBackPressed() {
        if (mWebview.isFocused() && mWebview.canGoBack()) {
            mWebview.goBack();       
        } else {
            super.onBackPressed();
            finish();
        }
    }

Solution 6 - Android

Why not use onBackPressed()?

@Override
public void onBackPressed() {
    // super.onBackPressed(); Do not call me!

    // Go to the previous web page.
}

Solution 7 - Android

In kotlin:

override fun onBackPressed() {
    when {
        webView.canGoBack() -> webView.goBack()
        else -> super.onBackPressed()
    }
}

webView - id of the webview component in xml, if using synthetic reference.

Solution 8 - Android

here is a code with confirm exit:

@Override
    public void onBackPressed()
    {
        if(webView.canGoBack()){
            webView.goBack();
        }else{
        	new AlertDialog.Builder(this)
            .setIcon(android.R.drawable.ic_dialog_alert)
            .setTitle("Exit!")
            .setMessage("Are you sure you want to close?")
            .setPositiveButton("Yes", new DialogInterface.OnClickListener()
	        {
	            @Override
	            public void onClick(DialogInterface dialog, int which) {
	                finish();    
	            }
	
	        })
	        .setNegativeButton("No", null)
	        .show();	
        }	
    }

Solution 9 - Android

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    // Check if the key event was the Back button and if there's history
    if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack()) {
        myWebView.goBack();
        return true;
    }
    // If it wasn't the Back key or there's no web page history, bubble up to the default
    // system behavior (probably exit the activity)
    return super.onKeyDown(keyCode, event);
}

Solution 10 - Android

The first answer by FoamyGuy is correct but I have some additions; low reputations cannot allow me to do comments. If for some reasons your page fails to load, ensure that you set a flag to take note of the failure and then check it on the onBackPressed override. Otherwise your canGoBack() will be forever executed without heading to the actual back activity if it was there:

//flag with class wide access 
public boolean ploadFailFlag = false;

//your error handling override
@Override
public void onReceivedError(WebView view, WebResourceRequest req, WebResourceError rerr) {
	onReceivedError(view, rerr.getErrorCode(), rerr.getDescription().toString(), req.getUrl().toString());
	ploadFailFlag = true;		//note this change 
	.....
	.....
}

//finally to the answer to this question:
@Override
public void onBackPressed() {
	if(checkinWebView.canGoBack()){
		//if page load fails, go back for web view will not go back - no page to go to - yet overriding the super 
		if(ploadFailFlag){
			super.onBackPressed();
		}else {
			checkinWebView.goBack();
		}
	}else {
		Toast.makeText(getBaseContext(), "super:", Toast.LENGTH_LONG).show();
		super.onBackPressed();
	}
}

Solution 11 - Android

You can try this for webview in a fragment:

private lateinit var webView: WebView

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    val root = inflater.inflate(R.layout.fragment_name, container, false)
    webView = root!!.findViewById(R.id.home_web_view)
    var url: String = "http://yoururl.com"
    webView.settings.javaScriptEnabled = true
    webView.webViewClient = WebViewClient()
    webView.loadUrl(url)
    webView.canGoBack()
    webView.setOnKeyListener{ v, keyCode, event ->
        if(keyCode == KeyEvent.KEYCODE_BACK && event.action == MotionEvent.ACTION_UP
            && webView.canGoBack()){
            webView.goBack()
            return@setOnKeyListener true
        }
        false
    }
    return root
}

Solution 12 - Android

You should the following libraries on your class handle the onBackKeyPressed. canGoBack() checks whether the webview can reference to the previous page. If it is possible then use the goBack() function to reference the previous page (go back).

 @Override
        public void onBackPressed() {
          if( mWebview.canGoBack()){
               mWebview.goBack(); 
           }else{
            //Do something else. like trigger pop up. Add rate app or see more app
           }
  }

Solution 13 - Android

Here is the Kotlin solution:

override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
    if (event?.action != ACTION_UP || event.keyCode != KEYCODE_BACK) {
        return super.onKeyUp(keyCode, event)
    }

    if (mWebView.canGoBack()) {
        mWebView.goBack()
    } else {
        finish()
    }
    return true
}

Solution 14 - Android

If someone wants to handle backPressed for a webView inside a fragment, then he can use below code.

  1. Copy below code into your Activity class (that contains a fragment YourFragmmentName)

    @Override
    public void onBackPressed() {
    List<Fragment> fragmentList = getSupportFragmentManager().getFragments();
    
    boolean handled = false;
    for(Object f: fragmentList) {
        if(f instanceof YourFragmentName) {
            handled = ((YourFragmentName)f).onBackPressed();
            if(handled) {
                break;
            }
        }
    }
    
    if(!handled) {
        super.onBackPressed();
    }
    

    }

  2. Copy this code in the fragment YourFragmentName

    public boolean onBackPressed() {
       if (webView.canGoBack()) {
           webView.goBack();
           return true;
       } else {
           return false;
       }
    }
    

Notes

  • Activity should be replaced with the actual Acitivity class you are using.

  • YourFragmentName should be replaced with the name of your Fragment.

  • Declare webView in YourFragmentName so that it can be accessed from within the function.

Solution 15 - Android

 WebView mWebView;

 mWebView = findViewById(R.id.webView);

    @Override
    public void onBackPressed() {
        if (webView.canGoBack()) {
            webView.goBack();
        } else {
            super.onBackPressed();
        }
    }

Solution 16 - Android

Official Kotlin Way:

override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
    // Check if the key event was the Back button and if there's history
    if (keyCode == KeyEvent.KEYCODE_BACK && myWebView.canGoBack()) {
        myWebView.goBack()
        return true
    }
    // If it wasn't the Back key or there's no web page history, bubble up to the default
    // system behavior (probably exit the activity)
    return super.onKeyDown(keyCode, event)
}

https://developer.android.com/guide/webapps/webview.html#NavigatingHistory

Solution 17 - Android

I think I'm a little late but according to the android documentation, you can have custom back navigation inside fragments done by the following piece of code.

 requireActivity().onBackPressedDispatcher.addCallback(this) {
            // Handle the back button event
            if (binding.webView.canGoBack()){
                binding.webView.goBack()
            } else {
                findNavController().popBackStack()
            }
        }

you can customize what to do when you the webView cant go back as per your needs.

Solution 18 - Android

use this code to go back on page and when last page came then go out of activity

 @Override
    public void onBackPressed() {
        super.onBackPressed();
        Intent intent=new Intent(LiveImage.this,DashBoard.class);
        startActivity(intent);
    }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionzvzejView Question on Stackoverflow
Solution 1 - AndroidFoamyGuyView Answer on Stackoverflow
Solution 2 - AndroidKevin WestwoodView Answer on Stackoverflow
Solution 3 - AndroidpetrnohejlView Answer on Stackoverflow
Solution 4 - AndroidParsania HardikView Answer on Stackoverflow
Solution 5 - AndroidZar E AhmerView Answer on Stackoverflow
Solution 6 - AndroidGyan aka Gary BuynView Answer on Stackoverflow
Solution 7 - Androidvishnu bennyView Answer on Stackoverflow
Solution 8 - AndroidMohammed AhmedView Answer on Stackoverflow
Solution 9 - AndroidMaheshView Answer on Stackoverflow
Solution 10 - AndroidAjowiView Answer on Stackoverflow
Solution 11 - AndroidSimbarashe MupfururirwaView Answer on Stackoverflow
Solution 12 - AndroidDaniel NyamasyoView Answer on Stackoverflow
Solution 13 - AndroidGiboltView Answer on Stackoverflow
Solution 14 - AndroidFaraz AhmadView Answer on Stackoverflow
Solution 15 - AndroidAbubakarView Answer on Stackoverflow
Solution 16 - AndroidSANATView Answer on Stackoverflow
Solution 17 - AndroidAmmar AhsanView Answer on Stackoverflow
Solution 18 - AndroidPradeep KumarView Answer on Stackoverflow