Android WebView із спотвореними символами UTF-8.


76

Я використовую деякі веб-перегляди у своєму додатку для Android, але не можу зробити так, щоб вони відображались у кодуванні utf-8.

Якщо використати цей, я не побачу своїх скандинавських статутів:

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

А якщо спробувати цей, я взагалі нічого не покажу

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

З повагою


1
хоча це дублікат android-webview-utf-8-not-show, прийняте рішення від 2010 року не працює з новішими версіями android. Відповіді від @ Cameron Lowell Palmer та @R Earle Harris у цьому питанні містять інформацію, яка працює для нових версій Android
k3b,

Точно, це схоже, але не дублікат, і це представляє сильніше загальне питання та відповідь. Проголосуйте, щоб знову відкрити.
Камерон Лоуелл Палмер

Олена Сис Здається, ваше закриття цього питання дещо корисне. Відповіді тут оцінені вище, ніж ваша відповідь, саме тому, що питання було досить іншим, а відповіді сильнішими.
Камерон Лоуелл Палмер

Це дублює питання: stackoverflow.com/questions/3312643 / ...
Jorgesys

@Elenasys не погоджується. Це схоже, але досить різне.
Cameron Lowell Palmer

Відповіді:


152

Ви можете спробувати відредагувати налаштування веб-перегляду, перш ніж завантажувати дані:

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

Також, як зазначено в коментарі нижче, обов’язково додайте "charset=utf-8"до виклику loadData:

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

1
Це не буде працювати, як описано в моїй відповіді. Проблема полягає в помилці методу, і вказівка ​​кодування UTF-8 при необхідності - це не все, що вам потрібно зробити.
Cameron Lowell Palmer

2
Це працює для Android 2.2, але щоб він працював і з Android 4.04, потрібно скористатися loadDataWithBaseURL()підходом, запропонованим Кемероном .
сулай

43
Це працює для мене на Android 2.2.1, 4.0.4, 4.1.2. Вам також потрібно додати "charset = utf-8" до виклику loadData. Ось так: webview.loadData (getString (R.string.info_texto), "text / html; charset = utf-8", "utf-8");
Derzu 24.03.13

130

Здається, це було порушено в якійсь формі чи моді назавжди. Випуск 1733

Використовуйте loadDataWithBaseURL замість 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);

Тепер справді дратує те, що на Samsung Galaxy S II (4.0.3) loadData () працює чудово, але при тестуванні на Galaxy Nexus (4.0.2) багатобайтові символи є спотвореними, якщо ви не використовуєте loadDataWithBaseURL ( ). Документація WebView

Останні версії Android

Деякі повідомляють про зміну поведінки викликів loadData, які вимагають mimeTypeвключення charset=utf-8.

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

Ви також можете використовувати цю формулу з 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);

Дивно, що Android все ще не вирішив цю основну проблему.


1
Дякую за це. Працював у мене досить добре.
Шон Гловер,

1
Дякую, мені добре працює на моєму Galaxy S3. Хоча це дратує.
nspo

Я не можу показати перевернутий знак оклику (¡, & # 161 ;, & iexcl;), використовуючи жоден із цих методів. Хтось знає, як це обійти?
Кассіо Лендім,

2
Я використовую Android 4.4.4 і не працював у мене. text/html; charset=utf-8працював.
Азад

1
Було б чудово мати остаточну відповідь щодо того, на якому рівні API це змінилося. При тестуванні на Samsung Galaxy S3 (API 16) "text / html; charset = utf-8" приводить до спотвореного тексту, тоді як "text / html" працює. У Moto G (API 23) все навпаки. Я вдався до використання if (Build.VERSION.SDK_INT> 16) для вибору рядка кодування, але я стурбований тим, що це все одно буде працювати не на всіх пристроях / Рівні API
QuantumTiger

27

Біт Дерзу дуже корисний вище:

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

Я мав utf-8 на Adroid 2.x і викривляв ansi на 4.x, поки не поставив

 charset=utf-8

у виклику wv.loadUrlWhatever (). Чудова увага до деталей, Дерзу


Додаткові настройки описані stackoverflow.com/a/4933345/866333 Еріка Нордвік навіть не потрібно. Принаймні не для 4.1.2
Іван,


12

Існує два способи, за допомогою яких сторінка HTML, яка доставляється сервером HTTP, може задавати кодування вмісту. Зазвичай сервер вказує кодування вмісту в заголовках HTTP, але оскільки ця сторінка завантажується з файлу, немає транзакції HTTP, а отже, і заголовків. Як результат, WebView приймає кодування за замовчуванням Latin-1.

Однак ви можете вказати кодування вмісту, використовуючи <meta>тег. Побудуйте свій HTML-файл таким чином:

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

А потім завантажте його у WebView за допомогою mWebView.loadUrl("file:///android_asset/om.html");. Він повинен відображати нелатинські символи, як ви очікуєте.


2
Це рішення мені було потрібне, оскільки я завантажую вміст html через файл. Подяка: D
Агунг Пратама

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

Здається, поєднання обох для мене працює. З якоїсь причини йому подобається null у кодуванні та коді в типі mime: / weird. це вирішило місяці загострення для мене.


Так, мені допомогли також лише ці два налаштування "utf-8". metaТег <meta http-equiv="content-type" content="text/html; charset=UTF-8">просто допоміг , коли я використовував , loadUrlале був проігнорований при використанні loadData(перевірено на API 16 + 21).
Дірк,

2

Вам потрібно поміняти місцями свої перші два аргументи. Дивіться цю тему: Android WebView UTF-8 не відображається

Отже, ваш код повинен виглядати так:

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

2
Відповідно до документації правильним є порядок: public void loadDataWithBaseURL (String baseUrl, String data, String mimeType, String encoding, String historyUrl)
Cameron Lowell Palmer

Так, документація правильна. Моя відповідь враховує це. Базова URL-адреса - це та, яка повинна бути нульовою.
Sparky

Це був той факт, що ваше корисне навантаження являло собою рядок з файлом: // через мене.
Камерон Лоуелл Палмер

1

Вам слід пам’ятати 3 речі, щоб завжди показувати правильний вміст:

  1. Використання loadDataWithBaseUrl замість функції loadData.
  2. Встановлення правильного кодування у файлі html як мета-тегу
  3. Встановлення defaultTextEncodingName у WebSettings

Приклади подані за допомогою інших відповідей, тому я не повторюю!


Ви пояснили, як переглядати вміст, що містить utf-8, а як щодо спільного використання URL-адреси, що містить utf-8, як це посилання (я хочу поділитися URL- адресами
Ахмад Ебрагімі

0

Я не впевнений, що ви робите до завантаження цієї сторінки. Чи може ця зміна безпеки мати щось спільне? Ви раніше завантажували сторінку з Інтернету?

Примітка до допису 1.0. Через зміну WebKit доступ до файлів активів через "file: /// android_asset /" для підресурсів є більш обмеженим. Якщо ви вказали нульовий або порожній рядок як baseUrl, ви не зможете отримати доступ до файлів активів. Якщо baseUrl - це щось інше, ніж http (s) / ftp (s) / about / javascript як схема, ви можете отримати доступ до файлів активів для підресурсів.

Взято звідси: http://developer.android.com/reference/android/webkit/WebView.html У розділі про метод "loadDataWithBaseURL".

Чи можете ви використовувати "loadData" замість цього для швидкого тесту? Вкажіть "utf-8" для кодування та вставки скандинавського символу в параметр даних. Простий тест для усунення проблеми безпеки.


0
mwebView.loadData(URLEncoder.encode(data, "utf-8").replaceAll("\\+"," "), "text/html", "utf-8");
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.