기계적 인조 인간. WebView 및 loadData


104

web-view loadData (String data, String mimeType, String encoding)의 콘텐츠 설정을 위해 다음과 같은 방법을 사용할 수 있습니다.

HTML 데이터의 알 수없는 인코딩 문제를 처리하는 방법?!

인코딩 목록이 있습니까?!

내 경우에는 html이 DB에서 왔고 latin-1로 인코딩되어 있다는 것을 대학에서 알고 있습니다. 인코딩 매개 변수를 latin-1, ISO-8859-1 / iso-8859-1로 설정하려고하지만 여전히 ä, ö, ü와 같은 특수 기호를 표시하는 데 문제가 있습니다.

조언을 해주셔서 감사합니다.

답변:


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

이것은 특히 HTML 내부의 문자 인코딩을 무시하는 Android 4.0에서 완벽하게 작동합니다 .

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 인코딩에서도 작동합니다! 그림을 이동.
Luis A. Florit 2013 년

2
@Frank Same 여기에서 HTC one 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 () 모두에서 UTF-8을 latin1 또는 ISO-8859-1로 바꿔야한다고 생각합니다.

그리고 완전한 답변을 제공하기 위해 다음은 공식 인코딩 목록입니다. http://www.iana.org/assignments/character-sets

더 포괄적으로 답변을 업데이트합니다.

Latin1 이 아닌 인코딩으로 WebView.loadData () 를 사용하려면 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
프리 벳, 안드레이. 나는 당신의 해결책을 시도했습니다. 불행히도 그것은 나를 위해 작동하지 않았습니다 :(
Tima

내가 설명한대로 UTF-8을 사용해 보셨습니까? 이제 귀하의 질문에 대해 생각할 때 Java에서 모든 문자열이 UTF-8로되어 있으므로 내 예제는 그대로 작동해야합니다.
Andrey Novikov

모든 문자열은 UTF-8이지만 서버에서 오는 텍스트는 latin-1입니다. UTF-8과 latin-1, ISO-8859-1로 시도했지만 ü, ö, ä 대신 여전히 이상한 기호를 보았습니다. 하지만 또 다른 아이디어가 있습니다. 올바른 인코딩을 사용하여 서버의 바이트 스트림을 문자열로 변환하려고합니다. 어쩌면, 그것은 나를 도와 줄게
TIMA

4
4.0에서 인코딩 MIME 설정해야 입력도 "텍스트 / HTML; chartset = UTF-8", 그렇지 않으면 인식되지
marwinXXII

2
마지막 스 니펫 (loadDataWithBaseURL 포함)은 4.2.2 및 2.3.6 기기 모두에서 훌륭하게 작동합니다. : D
Frank

36

내가 이해했듯이 loadData()단순히 data:데이터가 제공 하는 URL을 생성 합니다.

다음에 대한 javadocs 를 읽으십시오 loadData().

인코딩 매개 변수의 값이 'base64'인 경우 데이터는 base64로 인코딩되어야합니다. 그렇지 않으면 데이터는 안전한 URL 문자 범위 내의 옥텟에 대해 ASCII 인코딩을 사용하고 해당 범위를 벗어난 옥텟에 대한 URL의 표준 % xx 16 진 인코딩을 사용해야합니다. 예 : '#', '%', '\', '?' 각각 % 23, % 25, ​​% 27, % 3f로 바꿔야합니다.

이 방법으로 형성된 '데이터'스키마 URL은 기본 US-ASCII 문자 집합을 사용합니다. 다른 문자 세트를 설정해야하는 경우 URL의 미디어 유형 부분에 문자 세트 매개 변수를 명시 적으로 지정하는 '데이터'스키마 URL을 형성하고 대신 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

답변 해주셔서 감사합니다! webview에서 다른 내장 컨텍스트 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/…
Pascal

7

이것을 사용하십시오 : String customHtml = text;

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

15 포스트 나중에 그리고 이것은 나를 위해 일한 유일한 사람입니다
Guy Cothal

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

웹보기에서 htmlContent를로드 하는 가장 안전한 방법은 다음과 같습니다.

  1. base64 인코딩 사용 (공식 권장 사항)
  2. html 컨텐츠 유형에 대해 UFT-8을 지정하십시오 (예 : "text / html"(개인 조언) 대신 "text / html; charset = utf-8").

"Base64 인코딩"은 Chrominium최신 01/2019 버그 (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>

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.