Android defines html document and loads display in string.xml, and intercepts WebView link event

Keywords: Android xml Java encoding

I. how to define html document in string.xml

First of all, it's better to create a new html file by yourself, and then start writing your own content. And preview the effect in the browser.
First, write a simple html document in advance:

<html>
    <head>
        <style type="text/css">
            body {
                color: #111;
            }
        
            p {
                font-size: 1.5em;
            }
        </style>
    </head>
    <body>
        <h1>This is Title 1</h1>
        <p>This is a link</p>
        <a href="https://www.bing.com.cn">open bing</a>
    </body>
</html>

Then add the node in string.xml:

    <string name="html_content">
    <Data>
        <![CDATA[
<html>
    <head>
        <style type="text/css">
            body {
                color: #111;
            }

            p {
                font-size: 1.5em;
            }
        </style>
    </head>
    <body>
        <h1>This is Title 1</h1>
        <p>This is a link</p>
        <a href="https://Www.bing.com "> Open Bing</a>
    </body>
</html>
        ]]>
    </Data>
    </string>

The main thing is to include Data in the string node and wrap it with CDATA. In this way, the string obtained after using getResource().getString(), still contains only html text but not Data and CDATA labels. You can print and view in the next step. So it's also possible to read html directly from a file without having to put it in strings.xml.

2. Use WebView to display it

Create a new Activity with only one WebView.

<?xml version="1.0" encoding="utf-8"?>
<layout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        tools:context=".HtmlActivity"
>
    <WebView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/web_view"
    ></WebView>
</layout>

Load html in Activity.

class HtmlActivity : AppCompatActivity() {

    private lateinit var mBinding: ActivityHtmlBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_html)

        LoadHtmlTask().execute()
    }

    //Use AsyncTask to read HTML and load it. Of course, it can also be placed directly in the main thread. However, considering that HTML is generally large, or it may be
    //It will be read from the file, which is time consuming.
    //It is set to inner, which is equivalent to the ordinary inner class in java. If inner is not added, it will be equivalent to the static inner class in java by default in kotlin, which is inaccessible.
    //Of methods and properties of external classes.
    private inner class LoadHtmlTask: AsyncTask<Void, Void, String>
    {

        constructor()
        {

        }


        override fun doInBackground(vararg params: Void?): String {
            var s: String = resources.getString(R.string.html_content)
            return s
        }

        override fun onPostExecute(result: String?) {
            super.onPostExecute(result)
            if(result != null)
            {
                mBinding.webView.settings
                mBinding.webView.setBackgroundColor(Color.TRANSPARENT)
                mBinding.webView.isHorizontalScrollBarEnabled = false
                mBinding.webView.loadData(
                    result, "text/html; charset=UTF-8", null
                )
            }
        }
    }
}

Effect:

You can see that it's basically in the format we wrote. If you click the link, you will be prompted to open the browser and the bing page.

III. blocking link click events in WebView

You need to set up a WebViewClient for WebView.

override fun onPostExecute(result: String?) {
            super.onPostExecute(result)
            if(result != null)
            {
                mBinding.webView.settings
                mBinding.webView.setBackgroundColor(Color.TRANSPARENT)
                mBinding.webView.isHorizontalScrollBarEnabled = false
                mBinding.webView.loadData(
                    result, "text/html; charset=UTF-8", null
                )
				//Here is the writing method of Kotlin's anonymous inner class
                mBinding.webView.webViewClient = object: WebViewClient(){
                    override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
                        if (request?.url.toString().contains("bing.com.cn"))
                        {
                            openMailClient()
                            return true
                        }
                        return super.shouldOverrideUrlLoading(view, request)
                    }
                }
            }
        }

Then write the openMainClient method

private fun openMailClient() {
        var uri = Uri.parse("https://www.baidu.com")
        var intent = Intent(Intent.ACTION_VIEW, uri)

        startActivity(intent)
    }

After clicking the link, although the link is the bing URL, it has become Baidu's webpage due to our interception.

Posted by junkie_doodle on Wed, 30 Oct 2019 09:41:26 -0700