Android. WebView и loadData

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

Как решить проблему с неизвестной кодировкой html-данных ?!

А есть список кодировок ?!

Из своего колледжа я знаю, что в моем случае html исходит из БД и закодирован латинским-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 он просто показывает те же символы мусора. : S - 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, но текст, поступающий с сервера, представлен латинским-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; кодировка = utf-8, UTF-8); у меня сработало! - person letsdev-cwack; 10.07.2012
comment
в 4.0+ кодировка должна быть также установлена ​​в mime-типе 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-адреса mediatype и вместо этого вызывает loadUrl (String). Обратите внимание, что кодировка, полученная из части mediatype 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.0.1)). 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 (ноль, текст, «текст / HTML», «UTF-8», ноль);

person Celal Kanat    schedule 23.01.2017