Android. WebView и loadData

Възможно е да се използва следният метод за настройка на съдържанието на уеб изглед loadData(String data, String mimeType, String encoding)

Как да се справим с проблема с неизвестно кодиране на html данни?!

Има ли списък с кодировки?!

Знам от моя колеж, че в моя случай html идва от DB и е кодиран с latin-1. Опитвам се да задам параметър за кодиране на latin-1, на ISO-8859-1 / iso-8859-1, но все още имам проблем с показването на специални знаци като ä, ö, ü.

Ще съм много благодарен за всеки съвет.


person Tima    schedule 18.10.2010    source източник


Отговори (8)


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

Това работи безупречно, особено на Android 4.0, който очевидно пренебрегва кодирането на знаци в HTML.

Тестван на 2.3 и 4.0.3.

Всъщност нямам представа какви други стойности освен "base64" приема последният параметър. Някои примери на Google поставят null там.

person patryk    schedule 16.02.2012
comment
Това не може да работи безупречно, ако имате символи извън US-ASCII набор от знаци. - person Andrey Novikov; 01.03.2013
comment
Току-що пробвах на устройство 4.2.2 и работи като чар, но на устройство 2.3.6 просто показва същите боклуци. :С - person Frank; 11.05.2013
comment
Това също работи за мен в 4.1.2 (който също игнорира набор от знаци в HTML) и с кодиране Latin1! Дайте сметка. - person Luis A. Florit; 07.10.2013
comment
@Frank Същото тук, тествано на HTC one 2.3.7 (вероятно всички натруфени) и получих същия боклук, трябва да използвам решението на Андрей Новиков с WebView.loadDataWithBaseURL() - person ForceMagic; 27.05.2014
comment
Каква е разликата между вашия отговор и: myWebView.loadData(myHtmlString, text/html, UTF-8); - person Lou Morda; 05.06.2015
comment
документация казва, че приема US-ASCII за всичко друго освен "base64", включително null. - person Bart Friederichs; 06.03.2016
comment
base64 е необходим според препоръката на Google. Прочетете повече тук stackoverflow.com/questions/3961589/ и вижте видеоклипа на Google за това! (връзка в моя отговор ;-) - person Pascal; 29.07.2020

WebView.loadData() изобщо не работи правилно. Това, което трябваше да направя е:

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

Мисля, че във вашия случай трябва да замените UTF-8 с latin1 или ISO-8859-1 както в заглавката, така и в WebView.loadData().

И за да дадем пълен отговор, ето официалния списък с кодировки: http://www.iana.org/assignments/character-sets

Актуализирам отговора си, за да бъде по-всеобхватен:

За да използвате WebView.loadData() с кодировки, различни от latin1, трябва да кодирате html съдържание. Предишният пример не работеше правилно в Android 4+, така че го модифицирах така, че да изглежда по следния начин:

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

}

Но по-късно преминах към WebView.loadDataWithBaseURL() и кодът стана много чист и не зависи от версията на Android:

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

По някаква причина тези функции имат напълно различно изпълнение.

person Andrey Novikov    schedule 22.11.2010
comment
Лигуструм, Андрей. Опитах вашето решение. За съжаление не ми се получи :( - person Tima; 03.12.2010
comment
Опитвали ли сте UTF-8, както описах? Сега, когато мисля за вашия въпрос, ми хрумва, че в Java всички низове са в UTF-8, така че моят пример трябва да работи непокътнат. - person Andrey Novikov; 05.12.2010
comment
Всички низове са UTF-8, но текстът, идващ от сървъра, е на latin-1. Мисля, че опитах с UTF-8 и с latin-1 и с ISO-8859-1, но все още видях странни знаци вместо ü, ö, ä. Но имам друга идея, ще се опитам да преобразувам поток от байтове от сървъра в низ, като използвам правилното кодиране. може би това ще ми помогне - person Tima; 07.12.2010
comment
Да, мисля, че проблемът е там. Опитайте да тествате извеждането на този низ към Toast или Dialog и вижте какво ще получите. - person Andrey Novikov; 11.12.2010
comment
loadData(низ, текст/html; charset=utf-8, UTF-8); работи за мен! - person letsdev-cwack; 10.07.2012
comment
в 4.0+ кодирането трябва да бъде зададено и в mime type text/html; chartset=utf-8, в противен случай няма да бъде разпознат - person marwinXXII; 23.07.2012
comment
Последният фрагмент (този с loadDataWithBaseURL) работи чудесно както на 4.2.2, така и на 2.3.6 устройства :D - person Frank; 11.05.2013
comment
myWebView.loadDataWithBaseURL реши проблемите ми с Oreo+. Уеб изгледът не успяваше да изобрази нищо предварително. - person ShellDude; 19.01.2020
comment
Това не е правилно. google направи ясна препоръка за използване на base64. Вижте отговора ми и ПРОВЕРЕТЕ видео разговора ;-) stackoverflow.com/questions/3961589/ - person Pascal; 29.07.2020

Доколкото разбирам, loadData() просто генерира data: URL с предоставените данни.

Прочетете javadocs за loadData():

Ако стойността на параметъра за кодиране е „base64“, тогава данните трябва да бъдат кодирани като base64. В противен случай данните трябва да използват ASCII кодиране за октети в диапазона от безопасни URL знаци и да използват стандартното %xx шестнадесетично кодиране на URL адреси за октети извън този диапазон. Например, '#', '%', '\', '?' трябва да бъдат заменени съответно с %23, %25, %27, %3f.

URL адресът на схемата „данни“, формиран чрез този метод, използва набора от знаци US-ASCII по подразбиране. Ако трябва да зададете различен набор от знаци, трябва да формирате URL адрес на схема за „данни“, който изрично указва параметър за набор от знаци в частта за медийния тип на URL адреса и вместо това да извикате loadUrl(String). Обърнете внимание, че наборът от знаци, получен от частта за медийния тип на URL на данни, винаги заменя този, определен в самия HTML или XML документ.

Следователно трябва или да използвате US-ASCII и сами да избягвате всички специални знаци, или просто да кодирате всичко с помощта на Base64. Следното трябва да работи, ако приемем, че използвате UTF-8 (не съм тествал това с 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");
person Ralf    schedule 29.03.2012
comment
Това ми напомни да проверя документацията, преди да се скитам навсякъде! - person Pradeep; 20.04.2016
comment
Благодаря за отговора! Зареждаше различна вградена контекстуална html помощ в уеб изглед и работеше само част от времето. Това го поправи. - person eric; 31.12.2016

Имам този проблем, но:

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

не работи на всички устройства. И обединявам някои методи:

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

Работи.

person Aloyan Dmitry    schedule 13.05.2012
comment
Това НЕ е това, което Google препоръчва. Вижте отговора ми и ПРОВЕРЕТЕ видео разговора ;-) stackoverflow.com/questions/3961589/ - person Pascal; 29.07.2020

Най-безопасният начин за зареждане на htmlContent в уеб изглед е да:

  1. използвайте кодиране base64 (официална препоръка)
  2. посочете UFT-8 за тип html съдържание, т.е. "text/html; charset=utf-8" вместо "text/html" (личен съвет)

„Кодиране Base64“ е официална препоръка, която е написана отново (вече присъства в Javadoc) в най-новата грешка от 01/2019 в Chrominium (присъства в WebView M72 (72.0. 3626,76)):

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

Официално изявление от екипа на Chromium:

„Препоръчителна корекция:
Нашият екип препоръчва да кодирате данни с Base64. Предоставили сме примери как да го направите:

Тази корекция е обратно съвместима (работи на по-ранни версии на WebView) и също така трябва да е устойчива на бъдещето (няма да срещнете бъдещи проблеми със съвместимостта по отношение на кодирането на съдържанието)."

Примерен код:

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! 
person Pascal    schedule 10.02.2019

използвайте това: String customHtml =text ;

           wb.loadDataWithBaseURL(null,customHtml,"text/html", "UTF-8", null);
person krishna    schedule 10.01.2014
comment
15 публикации по-късно и това е единствената, която работи за мен - person Guy Cothal; 11.01.2020

отговорите по-горе не работят в моя случай. Трябва да посочите utf-8 в мета таг

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

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

person Celal Kanat    schedule 23.01.2017