Android. WebView e loadData


105

È possibile utilizzare il seguente metodo per l'impostazione del contenuto di una visualizzazione web loadData (String data, String mimeType, String encoding)

Come gestire il problema con la codifica sconosciuta dei dati HTML ?!

C'è un elenco di codifiche ?!

So dal mio college che nel mio caso html proviene da DB ed è codificato con latin-1. Provo a impostare il parametro di codifica su latin-1, ISO-8859-1 / iso-8859-1, ma ho ancora problemi con la visualizzazione di segni speciali come ä, ö, ü.

Sarò molto grato per qualsiasi consiglio.

Risposte:


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

Funziona perfettamente, specialmente su Android 4.0, che a quanto pare ignora la codifica dei caratteri all'interno dell'HTML.

Testato su 2.3 e 4.0.3.

In effetti, non ho idea di quali altri valori oltre a "base64" assumano l'ultimo parametro. Alcuni esempi di Google inseriscono null.


2
Questo non può funzionare "perfettamente" se hai caratteri al di fuori del set di caratteri US-ASCII.
Andrey Novikov

1
Appena provato su un dispositivo 4.2.2 e funziona come un fascino, ma su un dispositivo 2.3.6 mostra solo gli stessi caratteri spazzatura. : S
Frank

Questo funziona anche per me in 4.1.2 (che ignora anche il set di caratteri all'interno dell'HTML) e con una codifica Latin1! Vai a capire.
Luis A. Florit

2
@Frank Stesso qui, testato su HTC One 2.3.7 (probabilmente tutto pan di zenzero) e ho ottenuto la stessa spazzatura, devo usare la soluzione di Andrey Novikov conWebView.loadDataWithBaseURL()
ForceMagic

Qual è la differenza tra la tua risposta e: myWebView.loadData (myHtmlString, "text / html", "UTF-8");
Lou Morda

135

WebView.loadData () non funziona affatto correttamente. Quello che dovevo fare era:

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

Penso che nel tuo caso dovresti sostituire UTF-8 con latin1 o ISO-8859-1 sia nell'header che in WebView.loadData ().

E, per dare una risposta completa, ecco l'elenco ufficiale delle codifiche: http://www.iana.org/assignments/character-sets

Aggiorno la mia risposta per essere più inclusiva:

Per usare WebView.loadData () con codifiche non latin1 devi codificare il contenuto html. L'esempio precedente non funzionava correttamente in Android 4+, quindi l'ho modificato per apparire come segue:

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

}

Ma in seguito sono passato a WebView.loadDataWithBaseURL () e il codice è diventato molto pulito e non dipende dalla versione di Android:

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

Per qualche ragione queste funzioni hanno un'implementazione completamente diversa.


1
Privet, Andrey. Ho provato la tua soluzione. Sfortunatamente non ha funzionato per me :(
Tima

Hai provato UTF-8 come ho descritto? Ora, quando penso alla tua domanda, mi viene in mente che in Java tutte le stringhe sono in UTF-8, quindi il mio esempio dovrebbe funzionare intatto.
Andrey Novikov

Tutte le stringhe sono UTF-8, ma il testo proveniente dal server è in latino-1. Penso di aver provato con UTF-8 e con latin-1 e con ISO-8859-1, ma ho visto ancora segni strani invece di ü, ö, ä. Ma ho un'altra idea, proverò a convertire il flusso di byte dal server in una stringa usando la codifica corretta. forse, questo mi aiuterà
Tima

4
in 4.0+ la codifica dovrebbe essere impostata anche nel tipo MIME "text / html; chartset = utf-8", altrimenti non verrà riconosciuta
marwinXXII

2
L'ultimo snippet (quello con loadDataWithBaseURL) funziona alla grande sia su dispositivi 4.2.2 che 2.3.6: D
Frank

36

A quanto ho capito, loadData()genera semplicemente un filedata: URL con i dati forniti.

Leggi i javadoc per loadData():

Se il valore del parametro di codifica è "base64", i dati devono essere codificati come base64. In caso contrario, i dati devono utilizzare la codifica ASCII per gli ottetti all'interno dell'intervallo di caratteri URL sicuri e utilizzare la codifica esadecimale% xx standard degli URL per gli ottetti al di fuori di tale intervallo. Per esempio, '#', '%', '\', '?' dovrebbe essere sostituito rispettivamente da% 23,% 25,% 27,% 3f.

L'URL dello schema "dati" formato da questo metodo utilizza il set di caratteri US-ASCII predefinito. Se è necessario impostare un set di caratteri diverso, è necessario formare un URL di schema "dati" che specifichi esplicitamente un parametro del set di caratteri nella parte del tipo di carattere dell'URL e chiamare invece loadUrl (String). Si noti che il set di caratteri ottenuto dalla porzione del tipo di media di un URL di dati ha sempre la precedenza su quello specificato nel documento HTML o XML stesso.

Pertanto, dovresti usare US-ASCII ed eseguire da solo l'escape di eventuali caratteri speciali o semplicemente codificare tutto usando Base64. Quanto segue dovrebbe funzionare, supponendo che tu usi UTF-8 (non l'ho testato 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");

Questo mi ha ricordato di controllare la documentazione prima di vagare ovunque!
Pradeep

Grazie per la risposta! Stava caricando una diversa guida HTML contestuale incorporata in una visualizzazione Web e funzionava solo per alcune volte. Questo l'ha risolto.
Eric

20

Ho questo problema, ma:

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

non funziona in tutti i dispositivi. E unisco alcuni metodi:

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

Funziona.


Questo NON è ciò che Google consiglia. Guarda la mia risposta e CONTROLLA il video talk ;-) stackoverflow.com/questions/3961589/…
Pascal

7

usa questo: String customHtml = text;

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

15 post più tardi e questo è l'unico che ha funzionato per me
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

Il modo più sicuro per caricare htmlContent in una visualizzazione Web è:

  1. usa la codifica base64 (raccomandazione ufficiale)
  2. specifica UFT-8 per il tipo di contenuto html, ad esempio "text / html; charset = utf-8" invece di "text / html" (consiglio personale)

"Codifica Base64" è una raccomandazione ufficiale che è stata riscritta (già presente in Javadoc) nell'ultimo bug del 01/2019 in Chrominium (presente in WebView M72 (72.0.3626.76)):

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

Dichiarazione ufficiale del team di Chromium:

"Soluzione consigliata: il
nostro team consiglia di codificare i dati con Base64. Abbiamo fornito esempi su come farlo:

Questa correzione è retrocompatibile (funziona su versioni precedenti di WebView) e dovrebbe anche essere a prova di futuro (non incontrerai problemi di compatibilità futuri per quanto riguarda la codifica del contenuto). "

Esempio di codice:

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

le risposte sopra non funzionano nel mio caso. Devi specificare utf-8 nel meta tag

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.