Android. WebView und loadData


104

Es ist möglich, die folgende Methode zum Einstellen von LoadData in der Webansicht zu verwenden (String-Daten, String-MimeType, String-Codierung).

Wie gehe ich mit dem Problem mit der unbekannten Codierung von HTML-Daten um?!

Gibt es eine Liste von Codierungen?!

Ich weiß von meinem College, dass HTML in meinem Fall von DB stammt und mit Latin-1 codiert ist. Ich versuche, den Codierungsparameter auf Latin-1, ISO-8859-1 / ISO-8859-1 zu setzen, habe aber immer noch Probleme mit der Anzeige von Sonderzeichen wie ä, ö, ü.

Ich bin für jeden Rat sehr dankbar.

Antworten:


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

Dies funktioniert einwandfrei, insbesondere unter Android 4.0, bei dem die Zeichencodierung in HTML anscheinend ignoriert wird .

Getestet am 2.3 und 4.0.3.

Tatsächlich habe ich keine Ahnung, welche anderen Werte außer "base64" der letzte Parameter annimmt. Einige Google-Beispiele setzen dort null.


2
Dies kann nicht "fehlerfrei" funktionieren, wenn Sie Zeichen außerhalb des US-ASCII-Zeichensatzes haben.
— Andrey Novikov

1
Gerade auf einem 4.2.2-Gerät ausprobiert und funktioniert wie ein Zauber, aber auf einem 2.3.6-Gerät werden nur die gleichen Müllzeichen angezeigt. : S
— Frank

Dies funktioniert auch für mich in 4.1.2 (der auch Zeichensätze in HTML ignoriert) und mit einer Latin1-Codierung! Stelle dir das vor.
— Luis A. Florit

2
@Frank Gleich hier, getestet auf HTC One 2.3.7 (wahrscheinlich alle Lebkuchen) und habe den gleichen Müll, ich muss Andrey Novikov Lösung mitWebView.loadDataWithBaseURL()
— ForceMagic

Was ist der Unterschied zwischen Ihrer Antwort und: myWebView.loadData (myHtmlString, "text / html", "UTF-8");
— Lou Morda

135

WebView.loadData () funktioniert überhaupt nicht richtig. Was ich tun musste war:

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

Ich denke in Ihrem Fall sollten Sie UTF-8 sowohl im Header als auch in WebView.loadData () durch latin1 oder ISO-8859-1 ersetzen.

Um eine vollständige Antwort zu geben, finden Sie hier die offizielle Liste der Codierungen: http://www.iana.org/assignments/character-sets

Ich aktualisiere meine Antwort, um umfassender zu sein:

Um WebView.loadData () mit Nicht-Latin1-Codierungen zu verwenden, müssen Sie HTML-Inhalte codieren. Das vorherige Beispiel funktionierte in Android 4+ nicht richtig, daher habe ich es so geändert, dass es wie folgt aussieht:

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

}

Aber später habe ich zu WebView.loadDataWithBaseURL () gewechselt und der Code wurde sehr sauber und nicht abhängig von der Android-Version:

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

Aus irgendeinem Grund haben diese Funktionen eine völlig andere Implementierung.


1
Liguster, Andrey. Ich habe deine Lösung ausprobiert. Leider hat es bei mir nicht funktioniert :(
— Tima

Haben Sie UTF-8 wie beschrieben ausprobiert? Wenn ich jetzt über Ihre Frage nachdenke, fällt mir ein, dass in Java alle Zeichenfolgen in UTF-8 enthalten sind, sodass mein Beispiel intakt funktionieren sollte.
— Andrey Novikov

Alle Zeichenfolgen sind UTF-8, aber der vom Server kommende Text ist in Latein-1. Ich denke, ich habe es mit UTF-8 und mit Latin-1 und mit ISO-8859-1 versucht, aber immer noch seltsame Zeichen anstelle von ü, ö, ä gesehen. Aber ich habe eine andere Idee, ich werde versuchen, den Byte-Stream vom Server mit der richtigen Codierung in einen String umzuwandeln. Vielleicht hilft mir das
— Tima

4
in 4.0+ sollte die Kodierung auch im MIME-Typ "text / html; chartset = utf-8" eingestellt sein, sonst wird sie nicht erkannt
— marwinXXII

2
Das letzte Snippet (das mit loadDataWithBaseURL) funktioniert sowohl auf 4.2.2- als auch auf 2.3.6-Geräten hervorragend: D
— Frank

36

Soweit ich weiß, wird loadData()einfach eine data:URL mit den bereitgestellten Daten generiert .

Lesen Sie die Javadocs für loadData():

Wenn der Wert des Codierungsparameters 'base64' ist, müssen die Daten als base64 codiert werden. Andernfalls müssen die Daten die ASCII-Codierung für Oktette innerhalb des Bereichs sicherer URL-Zeichen und die Standard-Hex-Codierung% url für URLs außerhalb dieses Bereichs verwenden. Zum Beispiel, '#', '%', '\', '?' sollte durch% 23,% 25,% 27,% 3f ersetzt werden.

Die von dieser Methode gebildete 'Daten'-Schema-URL verwendet den Standard-US-ASCII-Zeichensatz. Wenn Sie einen anderen Zeichensatz festlegen müssen, sollten Sie eine 'Daten'-Schema-URL erstellen, die explizit einen Zeichensatzparameter im Mediatyp-Teil der URL angibt, und stattdessen loadUrl (String) aufrufen. Beachten Sie, dass der aus dem Mediatyp-Teil einer Daten-URL erhaltene Zeichensatz immer den im HTML- oder XML-Dokument selbst angegebenen überschreibt.

Daher sollten Sie entweder US-ASCII verwenden und Sonderzeichen selbst maskieren oder einfach alles mit Base64 codieren. Folgendes sollte funktionieren, vorausgesetzt, Sie verwenden UTF-8 (ich habe dies nicht mit latin1 getestet):

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

Dies erinnerte mich daran, die Dokumentation zu überprüfen, bevor ich überall herumwanderte!
— Pradeep

Danke für die Antwort! Wurde eine andere integrierte kontextbezogene HTML-Hilfe in eine Webansicht geladen, und es funktionierte nur teilweise. Dies hat es behoben.
— Eric

20

Ich habe dieses Problem, aber:

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

funktioniert nicht auf allen Geräten. Und ich füge einige Methoden zusammen:

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

Es klappt.


Dies ist NICHT das, was Google empfiehlt. Siehe meine Antwort und überprüfe das Videogespräch ;-) stackoverflow.com/questions/3961589/…
— Pascal

6

Verwenden Sie dies: String customHtml = text;

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

15 Post später und dies ist der einzige, der für mich gearbeitet hat
— 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

Der sicherste Weg, htmlContent in eine Webansicht zu laden, ist:

  1. Base64-Codierung verwenden (offizielle Empfehlung)
  2. Geben Sie UFT-8 für den HTML-Inhaltstyp an, dh "text / html; charset = utf-8" anstelle von "text / html" (persönlicher Rat).

"Base64-Codierung" ist eine offizielle Empfehlung, die im letzten 01/2019-Fehler in Chrominium (in WebView M72 (72.0.3626.76)) erneut geschrieben wurde (bereits in Javadoc vorhanden):

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

Offizielle Erklärung des Chromium-Teams:

"Empfohlener Fix:
Unser Team empfiehlt, dass Sie Daten mit Base64 codieren. Wir haben Beispiele dafür bereitgestellt:

Dieser Fix ist abwärtskompatibel (funktioniert mit früheren WebView-Versionen) und sollte auch zukunftssicher sein (zukünftige Kompatibilitätsprobleme in Bezug auf die Inhaltscodierung treten nicht auf). "

Codebeispiel:

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

Die obigen Antworten funktionieren in meinem Fall nicht. Sie müssen utf-8 im Meta-Tag angeben

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

-1

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.