WebView back history without redirects

16,456

Solution 1

I've just tested this on jellybean and it seems to work.

Essentially, whenever a new URL is loaded in the WebView keep a copy of the url.

On the next URL request, double check they we aren't already on this page, if they are, then go back in the webview history another step.

Essentially this is relying on the url passed into the override step being the redirected url, rather than the final redirected url.

public class MainActivity extends Activity {

    private Button mRefreshButton;
    private WebView mWebView;
    private String mCurrentUrl;

    public void onCreate(Bundle savedInstance) {
        super.onCreate(savedInstance);
        setContentView(R.layout.main);

        mWebView = (WebView) findViewById(R.id.webview);
        mRefreshButton = (Button) findViewById(R.id.refresh);

        mRefreshButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                 mWebView.reload();
            }
        });

        WebSettings webSettings = mWebView.getSettings();
        webSettings.setJavaScriptEnabled(true);

        mWebView.setWebViewClient(new WebViewClient() {

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                if(mCurrentUrl != null && url != null && url.equals(mCurrentUrl)) {
                    mWebView.goBack();
                    return true;
                }

                view.loadUrl(url);
                mCurrentUrl = url;
                return true;
            }
        });

        mWebView.loadUrl("http://www.gap.com/");
    }

    @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();
                        return true;
                    }
                    break;
            }

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

Solution 2

I hope this answer if anyone is still looking for it.I had been hunting to fix similar issues in my project and had tried multiple approaches like using - WebView.HitTestResult - Pushing the urls into the list - onKeyDown and so on... I think most of it would work if your app consists of just webview. But my project had a combination of native and webview and handles some native schema.

Essentially found that the key is how you override the method shouldOverrideUrlLoading. Since i wanted my app to handles some of the urls and the webview to handle some of the other ones especially the back handling.I used a flag for back presses something like ..

@Override
public void onBackPressed() {
  if (mWebView.canGoBack()) {
    mClient.setIsBackPressed(true);
    //mClient is an instance of the MyWebviewClient
    mWebView.goBack();
  } else {
    super.onBackPressed();
  }
}

public class MyWebviewClient extends WebViewClient {

  private Boolean isBackPressed = false;

  public void setIsBackPressed(Boolean isBackPressed) {
      this.isBackPressed = isBackPressed;
  }

  @Override
  public boolean shouldOverrideUrlLoading(WebView view, String url) {
      if (isBackPressed){
          return false;
      }
      else {
          // handle the url by implementing your logic
          return true;
      }
  }

  @Override
  public void onPageFinished(WebView view, String url) {
      isBackPressed = false;
      super.onPageFinished(view, url);
  }
}

In this way, whenever there is a redirect when you click back, then it return false and hence mocks the behaviour of the webview. At the same time, you make sure that the isBackPressed is set to false after the page finishes loading. Hope this helps !!

Share:
16,456

Related videos on Youtube

jrebecca1
Author by

jrebecca1

Updated on September 15, 2022

Comments

  • jrebecca1
    jrebecca1 over 1 year

    I implemented android webview and onKeyDown method for back key. (It implements webview.goBack();)

    My problem is exactly similar to the question in this post below (no answers there)

    How to control the Android WebView history/back stack?

    PROBLEM - When I press back button, webview selects the previous URL, but if that URL was actually a redirect, it goes into this vicious cycle/loop. If you look at chrome or stock browser it correctly handles the back without going back to the redirects.

    How can this be solved?

    Example: go to gap.com. Then select "My Gap Credit Card". This opens a redirect link and then the final page. Now when I click back, it never goes to Gap.com home page.

    Any suggestions...

    Additional Information: I did implement the shouldOverrideUrlLoading. If I remove that method, it seems to work fine but with this method it does not...

  • Beeing Jk
    Beeing Jk over 8 years
    doesn't work for my onBackPressed()..I need to click twice to get back to previous page