Android. WebView ve loadData


105

Bir web görünümü loadData içeriğinin ayarı için aşağıdaki yöntemi kullanmak mümkündür (Dize verileri, Dize mimeTürü, Dize kodlaması)

Html verilerinin bilinmeyen kodlanmasıyla ilgili sorun nasıl çözülür ?!

Kodlamaların bir listesi var mı ?!

Üniversitemden biliyorum ki benim durumumda html DB'den geliyor ve latin-1 ile kodlanıyor. Kodlama parametresini latin-1, ISO-8859-1 / iso-8859-1 olarak ayarlamaya çalışıyorum, ancak yine de ä, ö, ü gibi özel işaretlerin görüntülenmesinde sorun yaşıyorum.

Herhangi bir tavsiye için çok minnettar olacağım.

Yanıtlar:


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

Bu, özellikle HTML içindeki karakter kodlamasını görmezden gelen Android 4.0'da kusursuz bir şekilde çalışır .

2.3 ve 4.0.3'te test edilmiştir.

Aslında, son parametrenin "base64" dışında başka hangi değerleri aldığı hakkında hiçbir fikrim yok. Bazı Google örnekleri oraya boş değer koyuyor.


2
US-ASCII karakter kümesinin dışında karakterler varsa, bu "kusursuz" çalışamaz.
Andrey Novikov 13

1
Bir 4.2.2 cihazında denedim ve bir cazibe gibi çalışıyor, ancak bir 2.3.6 cihazında aynı anlamsız karakterleri gösteriyor. : S
Frank

Bu benim için 4.1.2'de (HTML içindeki karakter kümesini de yok sayan) ve Latin1 kodlamasında da işe yarıyor! Şekle gidin.
Luis A. Florit

2
@Frank Aynı burada, HTC One 2.3.7'de (muhtemelen tamamı zencefilli kurabiye) test edildi ve aynı çöpü aldım, Andrey Novikov çözümünüWebView.loadDataWithBaseURL()
ForceMagic

Cevabınız ve: myWebView.loadData (myHtmlString, "text / html", "UTF-8") arasındaki fark nedir;
Lou Morda

135

WebView.loadData () hiç düzgün çalışmıyor. Yapmam gereken şey şuydu:

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

Sanırım sizin durumunuzda UTF-8'i hem başlıkta hem de WebView.loadData () içinde latin1 veya ISO-8859-1 ile değiştirmelisiniz.

Ve tam bir cevap vermek için, işte kodlamaların resmi listesi: http://www.iana.org/assignments/character-sets

Cevabımı daha kapsayıcı olacak şekilde güncelliyorum:

Kullanmak için WebView.loadData () kodlamak html içeriğe sahip olmayan latin1 kodlamaları ile. Önceki örnek Android 4 + 'da düzgün çalışmıyordu, bu yüzden aşağıdaki gibi görünecek şekilde değiştirdim:

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

}

Ancak daha sonra WebView.loadDataWithBaseURL () ' ye geçtim ve kod çok temiz hale geldi ve Android sürümüne bağlı değil:

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

Bazı nedenlerden dolayı bu işlevler tamamen farklı bir uygulamaya sahiptir.


1
Privet Andrey. Çözümünüzü denedim. Maalesef benim için işe yaramadı :(
Tima

UTF-8'i tarif ettiğim gibi denediniz mi? Şimdi sorunuz hakkında düşündüğümde, Java'da tüm dizelerin UTF-8'de olduğu aklıma geliyor, bu yüzden örneğim bozulmadan çalışmalıdır.
Andrey Novikov

Tüm Dizeler UTF-8'dir, ancak sunucudan gelen metin latin-1'dir. Sanırım UTF-8, latin-1 ve ISO-8859-1 ile denedim, ancak ü, ö, ä yerine hala garip işaretler gördüm. Ama başka bir fikrim var, doğru kodlamayı kullanarak bayt akışını sunucudan dizeye dönüştürmeye çalışacağım. belki, bu bana yardımcı olur
Tima

4
4.0+ kodlamasında mime türünde de ayarlanmalıdır "text / html; chartset = utf-8", aksi takdirde tanınmayacaktır
marwinXXII

2
Son snippet (loadDataWithBaseURL içeren) hem 4.2.2 hem de 2.3.6 cihazlarda harika çalışıyor: D
Frank

36

Anladığım kadarıyla , verinin sağladığı loadData()bir data:URL oluşturuyor .

Oku javadocs için loadData():

Kodlama parametresinin değeri "base64" ise, verilerin base64 olarak kodlanması gerekir. Aksi takdirde, veriler, güvenli URL karakterleri aralığı içindeki sekizliler için ASCII kodlamasını kullanmalı ve bu aralığın dışındaki sekizliler için URL'lerin standart% xx onaltılık kodlamasını kullanmalıdır. Örneğin, '#', '%', '\', '?' sırasıyla% 23,% 25,% 27,% 3f ile değiştirilmelidir.

Bu yöntemle oluşturulan 'veri' düzeni URL'si varsayılan US-ASCII karakter kümesini kullanır. Farklı bir karakter kümesi ayarlamanız gerekiyorsa, URL'nin ortam türü bölümünde açıkça bir karakter kümesi parametresi belirten ve bunun yerine loadUrl (Dize) 'yi çağıran bir' veri 'şeması URL'si oluşturmalısınız. Bir veri URL'sinin ortam türü kısmından elde edilen karakter kümesinin her zaman HTML veya XML belgesinin kendisinde belirtilenleri geçersiz kıldığını unutmayın.

Bu nedenle, ya US-ASCII kullanmalı ve herhangi bir özel karakterden kendiniz kaçınmalısınız ya da Base64 kullanarak her şeyi kodlamalısınız. UTF-8 kullandığınızı varsayarak aşağıdakiler çalışmalıdır (bunu latin1 ile test etmedim):

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

Bu bana her yerde dolaşmadan önce belgeleri kontrol etmemi hatırlattı!
Pradeep

Cevap için teşekkürler! Bir web görünümünde farklı yerleşik html yardımı yükleniyordu ve sadece bir süre çalıştı. Bu onu düzeltti.
eric

20

Bu problemim var ama:

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

tüm cihazlarda çalışmaz. Ve bazı yöntemleri birleştiriyorum:

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

İşe yarıyor.


Google'ın önerdiği bu DEĞİLDİR. Cevabımı görün ve video konuşmasını KONTROL EDİN ;-) stackoverflow.com/questions/3961589/…
Pascal

7

şunu kullanın: String customHtml = text;

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

15 gönderi sonra ve bu benim için çalışan tek kişi
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);

5

En güvenli bir Web görünümünde htmlContent yük yöntemi nedir?

  1. base64 kodlamasını kullanın (resmi öneri)
  2. html içerik türü için UFT-8'i belirtin, yani "text / html" yerine "text / html; charset = utf-8" (kişisel tavsiye)

"Base64 kodlaması", Chrominium'daki en son 01/2019 hatasında (WebView M72'de (72.0.3626.76) mevcut ) yeniden yazılan ( Javadoc'ta zaten mevcut) resmi bir öneridir:

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

Chromium ekibinden resmi açıklama:

"Önerilen düzeltme:
Ekibimiz, verileri Base64 ile kodlamanızı önerir. Bunun nasıl yapılacağına ilişkin örnekler sağladık:

Bu düzeltme geriye dönük olarak uyumludur (önceki WebView sürümlerinde çalışır) ve aynı zamanda geleceğe yönelik olmalıdır (içerik kodlamayla ilgili olarak gelecekteki uyumluluk sorunlarına çarpmayacaksınız). "

Kod örneği:

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

Yukarıdaki cevaplar benim durumumda işe yaramıyor. Meta etiketinde utf-8 belirtmeniz gerekiyor

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

-1

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.