WebView de Android con caracteres UTF-8 confusos.

76

Estoy usando algunas vistas web en mi aplicación de Android, pero no puedo hacer que se muestren en codificación utf-8.

Si uso este, no veré mis caracteres escandinavos:

mWebView.loadUrl("file:///android_asset/om.html")

Y si prueba este, no se mostrará nada en absoluto.

mWebView.loadDataWithBaseURL("file:///android_asset/om.html", null, "text/html", "utf-8",null);

Saludos

elwis
fuente
1
aunque este es un duplicado de android-webview-utf-8-not-shows, la solución aceptada de 2010 no funciona con las versiones más recientes de Android. Las respuestas de @ Cameron Lowell Palmer y @R Earle Harris en esta pregunta contienen información que funciona para las versiones más recientes de Android
k3b
Exactamente, es similar, pero no un duplicado y esto representa una pregunta y respuesta general más fuerte. Vota para reabrir.
Cameron Lowell Palmer
Elena sys Parece que el cierre de esta pregunta es algo egoísta. Las respuestas aquí tienen una calificación más alta que su respuesta, precisamente porque la pregunta era lo suficientemente diferente y las respuestas más fuertes.
Cameron Lowell Palmer
Esta es una pregunta duplicada de: stackoverflow.com/questions/3312643/…
Jorgesys
@Elenasys no está de acuerdo. Es similar, pero suficientemente diferente.
Cameron Lowell Palmer

Respuestas:

152

Puede intentar editar la configuración de su vista web antes de cargar los datos:

WebSettings settings = mWebView.getSettings();
settings.setDefaultTextEncodingName("utf-8");

Además, como se "charset=utf-8"indica en el comentario a continuación, asegúrese de agregar a la llamada loadData:

mWebView.loadData(getString(R.string.info_texto), "text/html; charset=utf-8", "utf-8");
Eric Nordvik
fuente
1
Esto no funcionará como se describe en mi respuesta. El problema es un error en el método, y especificar la codificación UTF-8 mientras es necesario no es todo lo que necesita hacer.
Cameron Lowell Palmer
2
Esto funciona para Android 2.2, pero para que funcione también con Android 4.04, debe utilizar el loadDataWithBaseURL()enfoque sugerido por Cameron .
sulai
43
Eso me funciona en Android 2.2.1, 4.0.4, 4.1.2. También necesita agregar "charset = utf-8" a la llamada loadData. Así: webview.loadData (getString (R.string.info_texto), "text / html; charset = utf-8", "utf-8");
Derzu
130

Esto parece haberse roto de alguna forma para siempre. Edición 1733

Utilice loadDataWithBaseURL en lugar de loadData.

// Pretend this is an html document with those three characters
String scandinavianCharacters = "øæå";

// Won't render correctly
webView.loadData(scandinavianCharacters, "text/html", "UTF-8");

// Will render correctly
webView.loadDataWithBaseURL(null, scandinavianCharacters, "text/html", "UTF-8", null);

Ahora, la parte que es realmente molesta es que en el Samsung Galaxy S II (4.0.3) loadData () funciona bien, pero las pruebas en el Galaxy Nexus (4.0.2) los caracteres multibyte se distorsionan a menos que use loadDataWithBaseURL ( ). Documentación de WebView

Versiones recientes de Android

Algunos informan un cambio en el comportamiento de las llamadas loadData que requieren mimeTypeque se incluya charset=utf-8.

webView.loadData(scandinavianCharacters, "text/html; charset=utf-8", "UTF-8");

También puede utilizar esta formulación con WebSettings

WebView webView = (WebView) findViewById(R.id.DemoWebView);
WebSettings webSettings = webView.getSettings();
webSettings.setDefaultTextEncodingName("utf-8");  
webView.loadData(scandinavianCharacters, "text/html; charset=utf-8", null);

Es sorprendente que Android todavía no haya resuelto este problema básico.

Cameron Lowell Palmer
fuente
1
Gracias por esto. Me funcionó bastante bien.
Sean Glover
1
Gracias, funciona bien para mí en mi Galaxy S3. Aunque es molesto.
nspo
No puedo mostrar el signo de exclamación invertido (¡, & # 161 ;, & iexcl;) usando ninguno de estos métodos. ¿Alguien sabe cómo solucionar esto?
Cassio Landim
2
Estoy usando Android 4.4.4 y no funcionó para mí. text/html; charset=utf-8trabajó.
Azad
1
Sería genial tener una respuesta definitiva en cuanto a qué nivel de API cambió. En las pruebas en Samsung Galaxy S3 (API 16), "text / html; charset = utf-8" da como resultado texto confuso mientras que "text / html" funciona. En Moto G (API 23) es al revés He recurrido al uso de if (Build.VERSION.SDK_INT> 16) para seleccionar la cadena de codificación, pero me preocupa que esto todavía no funcione para todos los dispositivos / Niveles API
QuantumTiger
27

El bit de Derzu es muy útil arriba:

webview.loadData(getString(R.string.info_texto), "text/html; charset=utf-8", "utf-8"); 

Tenía utf-8 en Adroid 2.xy ansi confuso en 4.x hasta que puse el

 charset=utf-8

en la llamada wv.loadUrlWhatever (). Excelente atención al detalle, Derzu

R Earle Harris
fuente
Configuración adicional descrita en stackoverflow.com/a/4933345/866333 por Eric Nordvik ni siquiera es necesaria. Al menos no para 4.1.2
Juan
Genial: me salvó el tiempo
Dhruvil Patel
12

Hay dos formas en que una página HTML entregada por un servidor HTTP puede especificar la codificación del contenido. Por lo general, el servidor especificará la codificación del contenido en los encabezados HTTP, pero como esta página se carga desde un archivo, no hay transacción HTTP y, por lo tanto, no hay encabezados. Como resultado, WebView asume una codificación predeterminada de Latin-1.

Sin embargo, puede especificar una codificación de contenido mediante la <meta>etiqueta. Construya su archivo html así:

<!DOCTYPE HTML>
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <title>Title</title>
</head>
Your content following

Y luego cárguelo en WebView usando mWebView.loadUrl("file:///android_asset/om.html");. Debería mostrar los caracteres no latinos como esperas.

Aaron D
fuente
2
Esta solución es la que necesitaba, ya que cargo el contenido html a través de un archivo. Gracias: D
Agung Pratama
9
WebView wv = (WebView) findViewById(R.id.rowWebview);
WebSettings settings = wv.getSettings();
settings.setDefaultTextEncodingName("utf-8");                   
wv.loadData(topHtml, "text/html; charset=utf-8",null);

Una combinación de los dos parece funcionar para mí. Por alguna razón, le gusta null en la codificación y el juego de caracteres en el tipo mime: / weird. esto ha resuelto meses de agravamiento para mí.

usuario2860495
fuente
Sí, solo estas dos configuraciones de "utf-8" me ayudaron también. La metaetiqueta <meta http-equiv="content-type" content="text/html; charset=UTF-8">me ayudó cuando estaba usando, loadUrlpero fue ignorada cuando la usé loadData(probada en API 16 + 21).
Dirk
2

Necesita intercambiar sus dos primeros argumentos. Vea este hilo: Android WebView UTF-8 no se muestra

Entonces su código debería verse así:

mWebView.loadDataWithBaseURL(null, "file:///android_asset/om.html", "text/html", "utf-8",null);
Sparky
fuente
2
Según la documentación, el orden correcto es: public void loadDataWithBaseURL (String baseUrl, String data, String mimeType, String encoding, String historyUrl)
Cameron Lowell Palmer
Sí, la documentación es correcta. Mi respuesta tiene eso en cuenta. La URL base es la que debe ser nula.
Sparky
Fue el hecho de que su carga útil era una cadena con file: // que a través de mí.
Cameron Lowell Palmer
1

Debes tener en cuenta 3 cosas para mostrar el contenido correcto siempre:

  1. Usando loadDataWithBaseUrl en lugar de loadData funciton.
  2. Establecer la codificación correcta en el archivo html como una metaetiqueta
  3. Configuración de defaultTextEncodingName en WebSettings

Los ejemplos se han proporcionado a través de otras respuestas, ¡así que no repito!

Ali Hashemi
fuente
Explicó cómo ver el contenido que contiene utf-8, pero ¿qué pasa con compartir la URL que contiene utf-8, como este enlace (quiero compartir las URL en mi aplicación con las redes sociales): yazd20.com//News/2015/11/ استند-آب-كمدي-حسن-ريوندي-در-يزد. Html
Ahmad Ebrahimi
0

No estoy seguro de lo que está haciendo antes de cargar esa página. ¿Podría este cambio de seguridad tener algo que ver con eso? ¿Estás cargando una página desde la web antes?

Nota para la publicación 1.0. Debido al cambio en WebKit, el acceso a los archivos de activos a través de "file: /// android_asset /" para los recursos secundarios está más restringido. Si proporciona una cadena nula o vacía como baseUrl, no podrá acceder a los archivos de activos. Si baseUrl no es http (s) / ftp (s) / about / javascript como esquema, puede acceder a los archivos de activos para los recursos secundarios.

Tomado de aquí: http://developer.android.com/reference/android/webkit/WebView.html En la sección sobre el método "loadDataWithBaseURL".

¿Puede utilizar "loadData" en su lugar para una prueba rápida? Especifique "utf-8" para codificar y pegar un carácter escandinavo en el parámetro de datos. Prueba simple para eliminar el problema de seguridad.

Shakakai
fuente
0
mwebView.loadData(URLEncoder.encode(data, "utf-8").replaceAll("\\+"," "), "text/html", "utf-8");
PPD
fuente