Android WebView - navigating back on URL redirection

Viewed 8849

I have a question on the Android webview.

Assume URL A redirects to URL B.

My android application when it tries to open URL A, webview automatically redirects to URL B.

If a URL is being redirected to some other url, I see both these urls are stored in webview history. Now my webview history consists of [, , URL A, URL B ]

On back key click from URL B webpage, webview will try to load URL A, which again redirects to URL B. We need to double click back key to go back beyond URL A

How do I solve this issue ? Struggling from the past 2 hours :(

5 Answers

KOTLIN 2022

(Ignore some my codes, for example "intent.extras" or "with(webView.settings)" - if you don't need these settings of webView and yes I am not using viewBinding!!!)

Tried all my best to solve this problem + also fixed: when you clicking some toolbars in webpage which is something like show something without opening a new url, it was adding('cuz onTouch see below) current url again to our arrayList and when you were clicking "back" it was refreshing -> current url to current url. Best solution is here:

class WebActivity : AppCompatActivity(), View.OnTouchListener {
    private lateinit var url: String
    private lateinit var webView: WebView
    private lateinit var progressBar: ProgressBar
    private var mLastUrl: String? = null
    private val previous: ArrayList<String> = ArrayList()

    @SuppressLint("SetJavaScriptEnabled", "ClickableViewAccessibility")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_web)
        url = intent.extras!!.getString("url").toString()

        webView = findViewById(R.id.appWebView)
        progressBar = findViewById(R.id.webViewProgressBar)
        CookieManager.getInstance().setAcceptCookie(true)
        webView.webViewClient = (object : WebViewClient(){
            override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
                super.onPageStarted(view, url, favicon)
                progressBar.visibility = View.VISIBLE
            }

            override fun onPageFinished(view: WebView?, url: String?) {
                Log.i("DebugDebug", "OnPageFinished " + url);
                super.onPageFinished(view, url)
                mLastUrl = url
                progressBar.visibility = View.GONE
            }
        })
        webView.setOnTouchListener(this)

        with(webView.settings) {
            javaScriptEnabled = true
            javaScriptCanOpenWindowsAutomatically = true
            domStorageEnabled = true
            databaseEnabled = true
            loadWithOverviewMode = true
            useWideViewPort = true
            builtInZoomControls = true
            displayZoomControls = false
            setSupportZoom(true)
            defaultTextEncodingName = "utf-8"
        }
        webView.loadUrl(url)
    }

    @SuppressLint("ClickableViewAccessibility")
    override fun onTouch(v: View?, mE: MotionEvent?): Boolean {
        val hr = (v as WebView).hitTestResult
        if(hr != null && mLastUrl != null){
            if (previous.isEmpty() || previous[previous.size - 1] != mLastUrl) previous.add(mLastUrl!!)
        }
        Log.i("DebugDebug", "getExtra = " + hr.getExtra() + "\t\t Type = " + hr.getType())
        return false
    }

    override fun onBackPressed() {
        Log.i("DebugDebug", "onBackPressed loaded and removed" + previous.toString());
        if (previous.size > 0 && webView.url != previous[previous.size - 1]){
            webView.loadUrl(previous[previous.size - 1])
            previous.removeAt(previous.size - 1)
        }
    }
}
Related