Android. WebView і loadData


104

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

Як впоратися з проблемою з невідомим кодуванням HTML-даних ?!

Чи є список кодувань ?!

Я знаю з мого коледжу, що в моєму випадку html походить від БД і кодується латиною-1. Я намагаюся встановити параметр кодування на latin-1, на ISO-8859-1 / iso-8859-1, але все ще виникають проблеми з відображенням спеціальних знаків типу ä, ö, ü.

Я буду дуже вдячний за будь-яку пораду.

Відповіді:


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

Це працює бездоганно, особливо на Android 4.0, який, очевидно, ігнорує кодування символів всередині HTML.

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

Насправді я не маю уявлення про те, які інші значення, крім "base64", приймає останній параметр. Деякі приклади Google містять нуль.


2
Це не може працювати "бездоганно", якщо у вас є символи поза набором US-ASCII.
Андрій Новіков

1
Щойно спробував на пристрої 4.2.2 і працює як шарм, але на пристрої 2.3.6 він просто показує ті самі символи сміття. : S
Френк

Це також працює для мене в 4.1.2 (який також ігнорує діаграму всередині HTML) та з кодуванням Latin1! Піди розберися.
Луїс А. Флорит

2
@Frank Те саме тут, тестували на HTC один 2.3.7 (напевно, всі пряники) і отримали те саме сміття, я повинен використовувати рішення Андрія Новікова зWebView.loadDataWithBaseURL()
ForceMagic

Яка різниця між вашою відповіддю та: myWebView.loadData (myHtmlString, "text / html", "UTF-8");
Лу Морда

135

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

Чомусь ці функції мають зовсім іншу реалізацію.


1
Привет, Андрій. Я спробував ваше рішення. На жаль, це не спрацювало для мене :(
Тіма

Ви пробували UTF-8, як я описав? Тепер, коли я замислююся над вашим запитанням, мені здається, що в Java всі рядки є у UTF-8, тому мій приклад повинен працювати недоторканим.
Андрій Новіков

Усі рядки є UTF-8, але текст, що надходить із сервера, є латиницею 1. Я думаю, я спробував з UTF-8 і з латинією-1 і з ISO-8859-1, але все-таки побачив дивні знаки замість ü, ö, ä. Але в мене є інша ідея, я спробую перетворити байт-потік з сервера в рядок, використовуючи правильне кодування. можливо, це допоможе мені
Тима

4
в кодування 4.0+ слід встановити також тип mime "text / html; chartset = utf-8", інакше це не буде розпізнано
marwinXXII

2
Останній фрагмент (той із loadDataWithBaseURL) чудово працює як на пристроях 4.2.2, так і 2.3.6: D
Френк

36

Як я розумію, loadData()просто генерує data:URL-адресу з наданими даними.

Прочитайте javadocs для loadData():

Якщо значення параметра кодування дорівнює 'base64', то дані повинні бути кодовані як base64. В іншому випадку дані повинні використовувати кодування ASCII для октетів всередині діапазону безпечних символів URL-адреси та використовувати стандартне шестнадцяткове кодування URL-адрес для октетів поза цим діапазоном. Наприклад, '#', '%', '\', '?' слід замінити відповідно на% 23,% 25,% 27,% 3f.

URL-схема схеми "дані", сформована за допомогою цього методу, використовує стандартну схему US-ASCII. Якщо вам потрібно встановити іншу діаграму, вам слід сформувати URL-адресу схеми "дані", яка чітко вказує параметр charset у частині медіатипу URL-адреси та замість цього виклик loadUrl (String). Зауважте, що набір шаблонів, отриманих з медіатипової частини URL-адреси даних, завжди перекриває вказані в самому документі HTML або XML.

Тому ви повинні або використовувати US-ASCII і самостійно уникати будь-яких спеціальних символів, або просто кодувати все, використовуючи Base64. Слід працювати, якщо ви використовуєте UTF-8 (я не перевіряв це на латинській1):

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

Це нагадало мені перевірити документацію, перш ніж блукати скрізь!
Прадіп

Дякую за відповідь! Завантажували різні вбудовані в контекстну довідку HTML у веб-перегляді, і це працювало лише частину часу. Це зафіксувало це.
eric

20

У мене є ця проблема, але:

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

Це працює.


Google це не рекомендує. Дивіться мою відповідь і НЕ ПЕРЕВІРИТЕ відеозвернення ;-) stackoverflow.com/questions/3961589/…
Паскаль

7

використовувати це: String customHtml = текст;

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

15 повідомлення пізніше, і це єдиний, хто працював на мене
Гай Котхал,

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

Безпечний спосіб завантаження 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/isissue/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! 

1

відповіді вище не працює у моєму випадку. Вам потрібно вказати utf-8 у метатезі

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.