Androide. WebView y loadData

104

Es posible utilizar el siguiente método para la configuración de contenido de una vista web loadData (datos de cadena, tipo de cadena mime, codificación de cadena)

¿Cómo manejar el problema con la codificación desconocida de datos html?

¿Hay una lista de codificaciones?

Sé por mi universidad que, en mi caso, html proviene de DB y está codificado con latin-1. Intento establecer el parámetro de codificación en latin-1, en ISO-8859-1 / iso-8859-1, pero todavía tengo problemas con la visualización de signos especiales como ä, ö, ü.

Estaré muy agradecido por cualquier consejo.

Tima
fuente

Respuestas:

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

Esto funciona perfectamente, especialmente en Android 4.0, que aparentemente ignora la codificación de caracteres dentro de HTML.

Probado en 2.3 y 4.0.3.

De hecho, no tengo idea de qué otros valores además de "base64" toma el último parámetro. Algunos ejemplos de Google ponen nulo allí.

patryk
fuente
2
Esto no puede funcionar "perfectamente" si tiene caracteres fuera del juego de caracteres US-ASCII.
Andrey Novikov
1
Acabo de probarlo en un dispositivo 4.2.2 y funciona de maravilla, pero en un dispositivo 2.3.6 solo muestra los mismos caracteres basura. : S
Frank
Esto también me funciona en 4.1.2 (que también ignora el juego de caracteres dentro de HTML), ¡y con una codificación Latin1! Imagínate.
Luis A. Florit
2
@Frank Lo mismo aquí, probado en HTC one 2.3.7 (probablemente todo pan de jengibre) y obtuve la misma basura, tengo que usar la solución de Andrey Novikov conWebView.loadDataWithBaseURL()
ForceMagic
¿Cuál es la diferencia entre su respuesta y: myWebView.loadData (myHtmlString, "text / html", "UTF-8");
Lou Morda
135

WebView.loadData () no funciona correctamente en absoluto. Lo que tenía que hacer era:

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

Creo que en su caso debería reemplazar UTF-8 con latin1 o ISO-8859-1 tanto en el encabezado como en WebView.loadData ().

Y, para dar una respuesta completa, aquí está la lista oficial de codificaciones: http://www.iana.org/assignments/character-sets

Actualizo mi respuesta para que sea más inclusiva:

Para usar WebView.loadData () con codificaciones que no sean latin1, debe codificar el contenido html. El ejemplo anterior no funcionaba correctamente en Android 4+, así que lo modifiqué para que se vea de la siguiente manera:

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

}

Pero luego cambié a WebView.loadDataWithBaseURL () y el código se volvió muy limpio y no depende de la versión de Android:

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

Por alguna razón, estas funciones tienen una implementación completamente diferente.

Andrey Novikov
fuente
1
Privet, Andrey. Probé tu solución. Desafortunadamente, no funcionó para mí :(
Tima
¿Ha probado UTF-8 como lo describí? Ahora, cuando pienso en su pregunta, se me ocurre que en Java todas las cadenas están en UTF-8, por lo que mi ejemplo debería funcionar intacto.
Andrey Novikov
Todas las cadenas son UTF-8, pero el texto procedente del servidor está en latín-1. Creo que lo intenté con UTF-8 y con latin-1 y con ISO-8859-1, pero aún vi signos extraños en lugar de ü, ö, ä. Pero tengo otra idea, intentaré convertir el flujo de bytes del servidor en una cadena usando la codificación correcta. tal vez, eso me ayude
Tima
4
en la codificación 4.0+ también debe establecerse en tipo mime "text / html; chartset = utf-8", de lo contrario no se reconocerá
marwinXXII
2
El último fragmento (el que tiene loadDataWithBaseURL) funciona muy bien tanto en dispositivos 4.2.2 como 2.3.6: D
Frank
36

Según tengo entendido, loadData()simplemente genera una data:URL con los datos proporcionados.

Lea los javadocs para loadData():

Si el valor del parámetro de codificación es 'base64', los datos deben codificarse como base64. De lo contrario, los datos deben usar codificación ASCII para octetos dentro del rango de caracteres URL seguros y usar la codificación estándar% xx hexadecimal de URL para octetos fuera de ese rango. Por ejemplo, '#', '%', '\', '?' debe reemplazarse por% 23,% 25,% 27,% 3f respectivamente.

La URL del esquema de 'datos' formada por este método utiliza el juego de caracteres US-ASCII predeterminado. Si necesita configurar un juego de caracteres diferente, debe formar una URL de esquema de 'datos' que especifique explícitamente un parámetro de juego de caracteres en la parte del tipo de medio de la URL y, en su lugar, llame a loadUrl (String). Tenga en cuenta que el juego de caracteres obtenido de la parte del tipo de medio de una URL de datos siempre anula el especificado en el documento HTML o XML.

Por lo tanto, debe usar US-ASCII y escapar de cualquier carácter especial usted mismo, o simplemente codificar todo usando Base64. Lo siguiente debería funcionar, asumiendo que usa UTF-8 (no lo he probado con 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");
Ralf
fuente
¡Esto me recordó que revisara la documentación antes de deambular por todas partes!
Pradeep
¡Gracias por la respuesta! Estaba cargando diferentes ayudas html contextuales integradas en una vista web, y solo funcionó parte del tiempo. Esto lo ha arreglado.
Eric
20

Tengo este problema, pero:

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

no funciona en todos los dispositivos. Y fusiono algunos métodos:

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

Funciona.

Aloyan Dmitry
fuente
Esto NO es lo que recomienda Google. Vea mi respuesta y REVISE la charla de video ;-) stackoverflow.com/questions/3961589/…
Pascal
6

use esto: String customHtml = text;

           wb.loadDataWithBaseURL(null,customHtml,"text/html", "UTF-8", null);
Krishna
fuente
15 después y este es el único que funcionó para mí
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
fuente
5

La forma más segura de cargar htmlContent en una vista web es:

  1. usar codificación base64 (recomendación oficial)
  2. especifique UFT-8 para el tipo de contenido html, es decir, "text / html; charset = utf-8" en lugar de "text / html" (consejo personal)

La "codificación Base64" es una recomendación oficial que se ha escrito nuevamente (ya presente en Javadoc) en el último error de 01/2019 en Chrominium (presente en WebView M72 (72.0.3626.76)):

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

Declaración oficial del equipo de Chromium:

"Solución recomendada:
nuestro equipo recomienda que codifique los datos con Base64. Le proporcionamos ejemplos de cómo hacerlo:

Esta solución es compatible con versiones anteriores (funciona en versiones anteriores de WebView) y también debería estar preparada para el futuro (no tendrá problemas de compatibilidad en el futuro con respecto a la codificación de contenido) ".

Muestra de código:

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
fuente
1

las respuestas anteriores no funcionan en mi caso. Necesita especificar utf-8 en la metaetiqueta

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

webview.loadDataWithBaseURL (nulo, texto, "texto / html", "UTF-8", nulo);

Celal Kanat
fuente