安卓 WebView和loadData


104

可以使用以下方法对Web视图中的内容进行设置loadData(String data,String mimeType,String encoding)

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

有编码列表吗?

我从我的大学知道,就我而言,html来自DB,并使用latin-1编码。我尝试将编码参数设置为latin-1,设置为ISO-8859-1 / iso-8859-1,但仍然无法显示ä,ö,ü等特殊符号。

我将非常感谢您的任何建议。

Answers:


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

这完美无瑕,尤其是在Android 4.0上,后者显然忽略了HTML 内部的字符编码。

经过2.3和4.0.3测试。

实际上,我不知道最后一个参数除了“ base64”之外还需要其他什么值。Google的一些示例在其中放置了null。


2
如果您的字符超出了US-ASCII字符集,则无法“完美地”工作。
Andrey Novikov

1
刚在4.2.2设备上尝试过,并且像超级按钮一样工作,但是在2.3.6设备上,它只显示相同的垃圾字符。:S
Frank

这在4.1.2(也忽略HTML内的字符集)和Latin1编码的情况下对我也适用!去搞清楚。
路易斯·弗洛里特

2
@Frank同样,这里在HTC 2.3.7(可能是所有姜饼)上进行了测试,并得到了相同的垃圾,我必须使用Andrey Novikov解决方案,以及WebView.loadDataWithBaseURL()
ForceMagic 2014年

您的答案和:myWebView.loadData(myHtmlString,“ text / html”,“ UTF-8”)之间有什么区别?
Lou Morda 2015年

135

WebView.loadData()根本无法正常工作。我要做的是:

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

我认为在您的情况下,应在标头和WebView.loadData()中都用latin1或ISO-8859-1替换UTF-8。

并且,要给出完整的答案,以下是编码的官方列表:http : //www.iana.org/assignments/character-sets

我将答案更新为更具包容性:

要将WebView.loadData()与非latin1编码一起使用,您必须对html内容进行编码。前面的示例在Android 4+中无法正常工作,因此我将其修改为如下所示:

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);

}

但是后来我切换到WebView.loadDataWithBaseURL(),代码变得非常干净,并且不依赖于Android版本:

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

由于某些原因,这些功能的实现方式完全不同。


1
女贞,安德烈。我已经尝试过您的解决方案。不幸的是,它对我不起作用:(
蒂玛2010年

您是否按照我的描述尝试过UTF-8?现在,当我想到您的问题时,我发现在Java中所有字符串都在UTF-8中,因此我的示例应该完整无缺。
安德烈·诺维科夫

所有字符串均为UTF-8,但来自服务器的文本为latin-1。我想,我尝试使用UTF-8,latin-1和ISO-8859-1,但看到的仍然是奇怪的迹象,而不是ü,ö,ä。但是我有另一个想法,我将尝试使用正确的编码将来自服务器的字节流转换为字符串。也许会对我有帮助
蒂玛(Tima)2010年

4
在4.0+编码中,也应该在mime类型中设置“ text / html; chartset = utf-8”,否则将无法识别
marwinXXII

2
最后一个代码段(带有loadDataWithBaseURL的代码段)在4.2.2和2.3.6设备上均适用:D
Frank

36

据我了解,loadData()只需生成一个data:URL并提供数据即可。

阅读的javadocloadData()

如果encoding参数的值为'base64',则数据必须编码为base64。否则,数据必须对安全URL字符范围内的八位字节使用ASCII编码,并对超出该范围的八位字节使用标准的URL%xx十六进制编码。例如, '#', '%', '\', '?' 应分别替换为%23,%25,%27和%3f。

通过此方法形成的“数据”方案URL使用默认的US-ASCII字符集。如果需要设置其他字符集,则应形成一个“数据”方案URL,该URL在mediatype部分中显式指定一个charset参数,然后调用loadUrl(String)。请注意,从数据URL的媒体类型部分获得的字符集始终会覆盖HTML或XML文档本身中指定的字符集。

因此,您应该使用US-ASCII并自己转义任何特殊字符,或者仅使用Base64对所有内容进行编码。假设您使用的是UTF-8(我尚未使用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");

这提醒我在四处走走之前要检查文档!
Pradeep

感谢你的回答!在Web视图中加载了不同的内置上下文html帮助,并且仅在某些时间有效。这已经解决了。
eric

20

我有这个问题,但是:

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");

不适用于所有设备。我合并了一些方法:

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");

有用。


这不是Google的建议。见我的答案和做检查的视频通话;-) stackoverflow.com/questions/3961589/...
帕斯卡尔

6

使用这个:字符串customHtml = text;

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

15个帖子之后,这是唯一为我工作的
帖子

5
 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);

5

在Web视图中加载htmlContent 的最安全方法是:

  1. 使用base64编码(官方推荐)
  2. 为html内容类型指定UFT-8,即“ text / html; charset = utf-8”,而不是“ text / html”(个人建议)

“ Base64编码”是一项官方建议,已在Chrominium最新01/2019 bug(存在于WebView M72(72.0.3626.76))中再次写过(已经在Javadoc中提供):

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

Chromium小组的官方声明:

“建议的修正:
我们的团队建议您使用Base64对数据进行编码。我们提供了有关如何进行编码的示例:

此修补程序是向后兼容的(它在早期的WebView版本上可用),并且还应是面向未来的(就内容编码而言,您将来不会遇到兼容性问题)。”

代码示例:

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! 

1

上面的答案不适用于我。您需要在元标记中指定utf-8

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.