Android. WebView dan loadData

105

Ini memungkinkan untuk menggunakan metode berikut untuk setelan konten dari tampilan web loadData (Data string, Jenis mimeTipe, Pengodean string)

Bagaimana menangani masalah dengan pengkodean data html yang tidak diketahui ?!

Apakah ada daftar pengkodean ?!

Saya tahu dari kampus saya bahwa dalam kasus saya html berasal dari DB dan dikodekan dengan latin-1. Saya mencoba mengatur parameter encoding ke latin-1, ke ISO-8859-1 / iso-8859-1, tetapi masih bermasalah dengan tampilan tanda khusus seperti ä, ö, ü.

Saya akan sangat berterima kasih atas saran apa pun.

Tima
sumber

Jawaban:

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

Ini bekerja dengan sempurna, terutama pada Android 4.0, yang tampaknya mengabaikan pengkodean karakter di dalam HTML.

Diuji pada 2.3 dan 4.0.3.

Sebenarnya, saya tidak tahu apa nilai lain selain "base64" yang diambil oleh parameter terakhir. Beberapa contoh Google menempatkan nol di sana.

patryk
sumber
2
Ini tidak dapat bekerja "dengan sempurna" jika Anda memiliki karakter di luar rangkaian karakter US-ASCII.
Andrey Novikov
1
Baru saja mencoba pada perangkat 4.2.2 dan bekerja dengan baik, tetapi pada perangkat 2.3.6 hanya menunjukkan karakter sampah yang sama. : S
Frank
Ini juga berfungsi untuk saya di 4.1.2 (yang juga mengabaikan charset di dalam HTML), dan dengan encoding Latin1! Sosok pergi.
Luis A. Florit
2
@Frank Sama di sini, diuji pada HTC one 2.3.7 (mungkin semua roti jahe) dan mendapatkan sampah yang sama, saya harus menggunakan solusi Andrey Novikov denganWebView.loadDataWithBaseURL()
ForceMagic
Apa perbedaan antara jawaban Anda dan: myWebView.loadData (myHtmlString, "text / html", "UTF-8");
Lou Morda
135

WebView.loadData () sama sekali tidak berfungsi dengan baik. Yang harus saya lakukan adalah:

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

Saya pikir dalam kasus Anda, Anda harus mengganti UTF-8 dengan latin1 atau ISO-8859-1 baik di header dan di WebView.loadData ().

Dan, untuk memberikan jawaban lengkap, berikut adalah daftar resmi pengkodean: http://www.iana.org/assignments/character-sets

Saya memperbarui jawaban saya agar lebih inklusif:

Untuk menggunakan WebView.loadData () dengan penyandiaksaraan non latin1 Anda harus menyandikan konten html. Contoh sebelumnya tidak berfungsi dengan benar di Android 4+, jadi saya telah memodifikasinya agar terlihat seperti berikut:

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

}

Tapi kemudian saya beralih ke WebView.loadDataWithBaseURL () dan kodenya menjadi sangat bersih dan tidak tergantung pada versi Android:

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

Untuk beberapa alasan fungsi ini memiliki implementasi yang sangat berbeda.

Andrey Novikov
sumber
1
Privet, Andrey. Saya sudah mencoba solusi Anda. Sayangnya itu tidak berhasil untuk saya :(
Tima
Sudahkah Anda mencoba UTF-8 seperti yang saya jelaskan? Sekarang ketika saya memikirkan pertanyaan Anda, saya terpikir bahwa di Java semua string ada di UTF-8, jadi contoh saya harus berfungsi secara utuh.
Andrey Novikov
Semua String adalah UTF-8, tetapi teks yang berasal dari server dalam bahasa latin-1. Saya pikir, saya mencoba dengan UTF-8 dan dengan latin-1 dan dengan ISO-8859-1, tetapi saya masih melihat tanda-tanda aneh, bukan ü, ö, ä. Tapi saya punya ide lain, saya akan mencoba mengubah aliran byte dari server menjadi string menggunakan pengkodean yang benar. mungkin, itu akan membantu saya
Tima
4
dalam pengkodean 4.0+ harus disetel dalam jenis mime juga "text / html; chartset = utf-8", jika tidak maka tidak akan dikenali
marwinXXII
2
Cuplikan terakhir (yang memiliki loadDataWithBaseURL) berfungsi dengan baik pada perangkat 4.2.2 dan 2.3.6: D
Frank
36

Seperti yang saya pahami, loadData()cukup buat data:URL dengan data yang disediakan.

Baca javadocs untuk loadData():

Jika nilai parameter encoding adalah 'base64', maka data harus dienkode sebagai base64. Jika tidak, data harus menggunakan pengkodean ASCII untuk oktet di dalam rentang karakter URL yang aman dan menggunakan pengkodean hex standar% xx untuk oktet di luar rentang itu. Sebagai contoh, '#', '%', '\', '?' harus diganti masing-masing dengan% 23,% 25,% 27,% 3f.

URL skema 'data' yang dibentuk dengan metode ini menggunakan charset US-ASCII default. Jika Anda perlu menyetel charset yang berbeda, Anda harus membentuk URL skema 'data' yang secara eksplisit menentukan parameter charset di bagian mediatype dari URL dan sebagai gantinya memanggil loadUrl (String). Perhatikan bahwa charset yang diperoleh dari bagian mediatype URL data selalu menimpa yang ditentukan dalam dokumen HTML atau XML itu sendiri.

Oleh karena itu, Anda harus menggunakan US-ASCII dan melepaskan diri dari karakter khusus apa pun, atau cukup menyandikan semuanya menggunakan Base64. Berikut ini seharusnya berfungsi, dengan asumsi Anda menggunakan UTF-8 (Saya belum menguji ini dengan 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");
Ralf
sumber
Ini mengingatkan saya untuk memeriksa dokumentasi sebelum berkelana kemana-mana!
Pradeep
Terima kasih atas jawabannya! Sedang memuat bantuan html yang dibangun dalam kontekstual berbeda dalam tampilan web, dan itu hanya berfungsi beberapa saat. Ini telah memperbaikinya.
eric
20

Saya punya masalah ini, tapi:

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

tidak berfungsi di semua perangkat. Dan saya menggabungkan beberapa metode:

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

Berhasil.

Aloyan Dmitry
sumber
Ini BUKAN yang direkomendasikan Google. Lihat jawaban saya dan JANGAN PERIKSA obrolan video ;-) stackoverflow.com/questions/3961589/…
Pascal
7

gunakan ini: String customHtml = text;

           wb.loadDataWithBaseURL(null,customHtml,"text/html", "UTF-8", null);
krishna
sumber
15 posting kemudian dan ini adalah satu-satunya yang berhasil untuk saya
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);
Yiğit
sumber
5

Cara paling aman untuk memuat htmlContent dalam tampilan Web adalah:

  1. gunakan pengkodean base64 (rekomendasi resmi)
  2. tentukan UFT-8 untuk jenis konten html, misalnya, "text / html; charset = utf-8" bukan "text / html" (saran pribadi)

"Pengkodean Base64" adalah rekomendasi resmi yang telah ditulis lagi (sudah ada di Javadoc) di bug 01/2019 terbaru di Chrominium (hadir di WebView M72 (72.0.3626.76)):

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

Pernyataan resmi dari tim Chromium:

"Perbaikan yang disarankan:
Tim kami menyarankan Anda mengenkode data dengan Base64. Kami telah memberikan contoh cara melakukannya:

Perbaikan ini kompatibel dengan versi sebelumnya (berfungsi pada versi WebView sebelumnya), dan juga harus tahan masa depan (Anda tidak akan mengalami masalah kompatibilitas di masa mendatang sehubungan dengan pengkodean konten). "

Contoh kode:

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! 
Pascal
sumber
1

jawaban di atas tidak berfungsi dalam kasus saya. Anda perlu menentukan utf-8 di tag meta

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

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

Celal Kanat
sumber