78

I'm using some webviews in my android app, but are unable to make them display in utf-8 encoding.

If use this one I won't see my scandinavian charcters:

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

And if try this one, I won't get anything displayed at all

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

Regards

Cameron Lowell Palmer
  • 21,528
  • 7
  • 125
  • 126
elwis
  • 1,395
  • 2
  • 20
  • 34
  • 1
    although this is a duplicate of [android-webview-utf-8-not-showing](http://stackoverflow.com/questions/3312643/android-webview-utf-8-not-showing) the accepted solution from 2010 does not work with newer android versions. Answers from @ Cameron Lowell Palmer and @R Earle Harris in this question contain info that works for newer android-versions – k3b May 28 '15 at 09:03
  • Exactly, it is similar, but not a duplicate and this represents a stronger general question and answer. Please vote to reopen. – Cameron Lowell Palmer Mar 06 '16 at 07:06
  • Elena sys It seems your closing of this question is somewhat self-serving. The answers here are higher rated than your answer, precisely because the question was sufficiently different and the answers stronger. – Cameron Lowell Palmer Mar 06 '16 at 07:12
  • This is a duplicated question of : http://stackoverflow.com/questions/3312643/android-webview-utf-8-not-showing/ – Jorgesys Mar 06 '16 at 17:27
  • @Elenasys disagree. It is similar, but sufficiently different. – Cameron Lowell Palmer Mar 08 '16 at 07:58

9 Answers9

158

You can try to edit the settings of your webview before you load the data:

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

Also, as provided in the comment below, be sure to add "charset=utf-8" to the loadData call:

mWebView.loadData(getString(R.string.info_texto), "text/html; charset=utf-8", "utf-8");
Dielson Sales
  • 1,715
  • 1
  • 20
  • 25
Eric Nordvik
  • 14,656
  • 8
  • 42
  • 50
  • 1
    This will not work as described in my answer. The issue is a bug in the method, and specifying UTF-8 encoding while necessary is not all you need to do. – Cameron Lowell Palmer Jul 14 '12 at 08:42
  • 2
    This works for Android 2.2, but to have it working with Android 4.04 too, you need to use the `loadDataWithBaseURL()` approach [suggested by Cameron](http://stackoverflow.com/a/10831462/1208581). – sulai Oct 12 '12 at 09:20
  • 43
    That works for me on android 2.2.1, 4.0.4, 4.1.2 . You also need to add "charset=utf-8" to the loadData call. Like that: webview.loadData(getString(R.string.info_texto), "text/html; charset=utf-8", "utf-8"); – Derzu Mar 24 '13 at 22:22
135

This seems to have been broken in some form or fashion forever. Issue 1733

Use loadDataWithBaseURL instead of 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);

Now the part that is truly annoying is that on the Samsung Galaxy S II (4.0.3) loadData() works just fine, but testing on the Galaxy Nexus (4.0.2) the multi-byte characters are garbled unless you use loadDataWithBaseURL(). WebView Documentation

Recent versions of Android

Some are reporting a change in the behavior of the loadData calls requiring the mimeType to include charset=utf-8.

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

You can also use this formulation with 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);

It is amazing that Android still hasn't resolved this basic issue.

Cameron Lowell Palmer
  • 21,528
  • 7
  • 125
  • 126
  • 1
    Thanks for this. Worked for me quite well. – Sean Glover Sep 04 '12 at 19:38
  • 1
    Thank you, works fine for me on my Galaxy S3. It's annoying though. – nspo Mar 16 '13 at 19:46
  • I'm not being able to show the inverted exclamation point (¡, ¡, ¡) using any of these methods. Does anyone know how to work this around? – Cassio Landim Jul 10 '13 at 12:45
  • @CassioLandim You'll need to give a bit more detail – Cameron Lowell Palmer Aug 22 '13 at 14:18
  • 2
    I'm using android 4.4.4 and didn't work for me. `text/html; charset=utf-8` worked. – Azad Mar 09 '15 at 15:11
  • @Azad would be nice to know more specifics than 4.4.4. Google, HTC, Samsung? I went ahead and added the information to improve the answer – Cameron Lowell Palmer Mar 11 '15 at 09:39
  • 1
    It would be great to have a definitive answer as to which API level this changed. In testing on Samsung Galaxy S3 (API 16) "text/html; charset=utf-8" results in garbled text whilst "text/html" works. On Moto G (API 23) it is the other way around.I have resorted to using if (Build.VERSION.SDK_INT > 16) to select the encoding string, but I am concerned that this still won't work for all devices/API levels – QuantumTiger Jul 11 '16 at 10:13
27

Derzu's bit is very helpful above:

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

I had UTF-8 on Android 2.x and garbled ANSI on 4.x until I put in the

 charset=utf-8

in the wv.loadUrlWhatever() call. Excellent attention to detail, Derzu

Axifive
  • 1,159
  • 2
  • 19
  • 31
R Earle Harris
  • 985
  • 9
  • 17
  • Extra setting described http://stackoverflow.com/a/4933345/866333 by Eric Nordvik not even needed. At least not for 4.1.2 – John Sep 11 '14 at 23:28
12

There are two ways that a HTML page delivered by a HTTP server can specify the content encoding. Usually, the server will specify the content encoding in the HTTP headers, but since this page is being loaded from a file, there is no HTTP transaction and therefore no headers. As a result, WebView assumes a default encoding of Latin-1.

However, you can specify a content encoding using the <meta> tag. Construct your html file thus:

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

And then load it into WebView using mWebView.loadUrl("file:///android_asset/om.html");. It should display the non-latin characters as you expect.

Aaron D
  • 7,540
  • 3
  • 44
  • 48
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);

A combination of the two seems to work for me. For some reason it likes null on the encoding and the charset in the mime type :/ weird. this has solved months of aggravation for me.

Joe
  • 15,205
  • 8
  • 49
  • 56
user2860495
  • 91
  • 1
  • 1
  • Yes, only these two settings of "utf-8" helped me too. The `meta` tag `` just helped when I was using `loadUrl` but was ignored when using `loadData` (tested on API 16 + 21). – Dirk Nov 20 '14 at 20:30
2

You need to swap your first two arguments. See this thread: Android WebView UTF-8 not showing

So your code should look like this:

mWebView.loadDataWithBaseURL(null, "file:///android_asset/om.html", "text/html", "utf-8",null);
Community
  • 1
  • 1
Sparky
  • 8,437
  • 1
  • 29
  • 41
1

You should keep 3 things in mind to show the right content always:

  1. Using loadDataWithBaseUrl instead of loadData funciton.
  2. Setting the correct encoding in html file as a meta tag
  3. Setting defaultTextEncodingName in WebSettings

The examples have been provided via other answers so I don't repeat!

Ali Hashemi
  • 3,158
  • 3
  • 34
  • 48
  • You explained about how to view content containing utf-8, but what about sharing url containing utf-8, like this link (I want to share Urls in my app with social networks): http://yazd20.com//News/2015/11/استند-آب-كمدي-حسن-ريوندي-در-يزد.html – Ahmad Ebrahimi Nov 02 '15 at 21:07
0
mwebView.loadData(URLEncoder.encode(data, "utf-8").replaceAll("\\+"," "), "text/html", "utf-8");
PPD
  • 5,660
  • 12
  • 52
  • 86
0

I'm not sure what you are doing prior to loading that page. Could this security change have anything to do with it? Are you loading page from web before?

Note for post 1.0. Due to the change in the WebKit, the access to asset files through "file:///android_asset/" for the sub resources is more restricted. If you provide null or empty string as baseUrl, you won't be able to access asset files. If the baseUrl is anything other than http(s)/ftp(s)/about/javascript as scheme, you can access asset files for sub resources.

Taken from here: http://developer.android.com/reference/android/webkit/WebView.html In the section on method "loadDataWithBaseURL".

Can you use "loadData" instead for a quick test? Specify "utf-8" for the encoding and pasting a scandinavian character into the data parmeter. Simple test to remove the security issue.

Shakakai
  • 3,514
  • 1
  • 16
  • 18