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.

Tima
quelle

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.

patryk
quelle
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.

Andrey Novikov
quelle
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");
Ralf
quelle
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.

Aloyan Dmitry
quelle
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);
krishna
quelle
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);
Yiğit
quelle
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! 
Pascal
quelle
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>
Truong Nguyen
quelle
-1

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

Celal Kanat
quelle