WebView 和 loadData

可以使用以下方法来设置网页视图的内容 LoadData (字符串数据,字符串 mimeType,字符串编码)

如何处理 HTML 数据未知编码的问题? !

有编码清单吗!

我从我的大学知道,在我的情况下,html 来自数据库,并用拉丁文1编码。 我尝试将编码参数设置为 latin-1,即 ISO-8859-1/ISO-8859-1,但是在显示诸如 ä、 ö、 ü 之类的特殊符号时仍然存在问题。

我非常感谢你的建议。

151962 次浏览

WebView.loadData() is not working properly at all. What I had to do was:

String header = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>";
myWebView.loadData(header+myHtmlString, "text/html", "UTF-8");

I think in your case you should replace UTF-8 with latin1 or ISO-8859-1 both in header and in WebView.loadData().

And, to give a full answer, here is the official list of encodings: http://www.iana.org/assignments/character-sets

I update my answer to be more inclusive:

To use WebView.loadData() with non latin1 encodings you have to encode html content. Previous example was not correctly working in Android 4+, so I have modified it to look as follows:

WebSettings settings = myWebView.getSettings();
settings.setDefaultTextEncodingName("utf-8");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
String base64 = Base64.encodeToString(htmlString.getBytes(), Base64.DEFAULT);
myWebView.loadData(base64, "text/html; charset=utf-8", "base64");
} else {
String header = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>";
myWebView.loadData(header + htmlString, "text/html; charset=UTF-8", null);


}

But later I have switched to WebView.loadDataWithBaseURL() and the code became very clean and not depending on Android version:

WebSettings settings = myWebView.getSettings();
settings.setDefaultTextEncodingName("utf-8");
myWebView.loadDataWithBaseURL(null, htmlString, "text/html", "utf-8", null);

For some reason these functions have completely different implementation.

myWebView.loadData(myHtmlString, "text/html; charset=UTF-8", null);

This works flawlessly, especially on Android 4.0, which apparently ignores character encoding inside HTML.

Tested on 2.3 and 4.0.3.

In fact, I have no idea about what other values besides "base64" does the last parameter take. Some Google examples put null in there.

the answers above doesn't work in my case. You need to specify utf-8 in meta tag

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<!-- you content goes here -->
</body>
</html>

As I understand it, loadData() simply generates a data: URL with the data provide it.

Read the javadocs for loadData():

If the value of the encoding parameter is 'base64', then the data must be encoded as base64. Otherwise, the data must use ASCII encoding for octets inside the range of safe URL characters and use the standard %xx hex encoding of URLs for octets outside that range. For example, '#', '%', '\', '?' should be replaced by %23, %25, %27, %3f respectively.

The 'data' scheme URL formed by this method uses the default US-ASCII charset. If you need need to set a different charset, you should form a 'data' scheme URL which explicitly specifies a charset parameter in the mediatype portion of the URL and call loadUrl(String) instead. Note that the charset obtained from the mediatype portion of a data URL always overrides that specified in the HTML or XML document itself.

Therefore, you should either use US-ASCII and escape any special characters yourself, or just encode everything using Base64. The following should work, assuming you use UTF-8 (I haven't tested this with latin1):

String data = ...;  // the html data
String base64 = android.util.Base64.encodeToString(data.getBytes("UTF-8"), android.util.Base64.DEFAULT);
webView.loadData(base64, "text/html; charset=utf-8", "base64");

I have this problem, but:

String content = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" /></head><body>";
content += mydata + "</body></html>";
WebView1.loadData(content, "text/html", "UTF-8");

not work in all devices. And I merge some methods:

String content =
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"+
"<html><head>"+
"<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" />"+
"</head><body>";


content += myContent + "</body></html>";


WebView WebView1 = (WebView) findViewById(R.id.webView1);
WebView1.loadData(content, "text/html; charset=utf-8", "UTF-8");

It works.

 String strWebData="html...." //**Your html string**


WebView webDetail=(WebView) findViewById(R.id.webView1);


WebSettings websetting = webDetail.getSettings();


websetting.setDefaultTextEncodingName("utf-8");


webDetail.loadData(strWebData, "text/html; charset=utf-8", null);

use this: String customHtml =text ;

           wb.loadDataWithBaseURL(null,customHtml,"text/html", "UTF-8", null);

The safest way to load htmlContent in a Web view is to:

  1. use base64 encoding (official recommendation)
  2. specify UFT-8 for html content type, i.e., "text/html; charset=utf-8" instead of "text/html" (personal advice)

"Base64 encoding" is an official recommendation that has been written again (already present in Javadoc) in the latest 01/2019 bug in Chrominium (present in WebView M72 (72.0.3626.76)):

https://bugs.chromium.org/p/chromium/issues/detail?id=929083

Official statement from Chromium team:

"Recommended fix:
Our team recommends you encode data with Base64. We've provided examples for how to do so:

This fix is backwards compatible (it works on earlier WebView versions), and should also be future-proof (you won't hit future compatibility problems with respect to content encoding)."

Code sample:

webView.loadData(
Base64.encodeToString(
htmlContent.getBytes(StandardCharsets.UTF_8),
Base64.DEFAULT), // encode in Base64 encoded
"text/html; charset=utf-8", // utf-8 html content (personal recommendation)
"base64"); // always use Base64 encoded data: NEVER PUT "utf-8" here (using base64 or not): This is wrong!

this is fast and working // data = any html or math string

public void putInWebview(String data, WebView wv) {
String htmlstring = "<head><meta name='viewport' content='width=device-width, shrink-to-fit=YES' user-scalable='no'><script type=\"text/x-mathjax-config\">MathJax.Hub.Config({tex2jax: {inlineMath: [['\\(','\\)']],processEscapes: true},\"HTML-CSS\": { linebreaks: { automatic: true, width: \"container\" } } } )</script><script id=\"MathJax-script\" async src=\"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js\" ></script></head>" +
"<body style=\"font-size:100%; font-family: Arial \"  > " + data + "</body></html>";
String qstnencodedHtml = Base64.encodeToString(htmlstring.getBytes(), Base64.NO_PADDING);
if (Build.VERSION.SDK_INT >= 19) {
wv.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
else {
wv.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
wv.getSettings().setJavaScriptEnabled(true);
wv.loadData(qstnencodedHtml, "text/html", "base64");


}