Lollipop中的WebView不会从资源加载字体

时间:2014-12-04 15:00:10

标签: android html webview assets android-5.0-lollipop

我使用WebView呈现一些HTML内容。在我的CSS中,我有以下代码:

@font-face {
  font-family: CharterC;
  font-style: normal;
  font-weight: normal;
  src: url("asset://fonts/CharterC.otf");
}

我的WebViewClient

中有以下Java代码
    @Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
    if (url.startsWith(ASSETS_SCHEME)) {
        String asset = url.substring(ASSETS_SCHEME.length());
        if (asset.endsWith(".js")) {
            try {
                return new WebResourceResponse("text/javascript", "utf-8", context.getAssets().open(asset));
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (asset.endsWith(".ttf") || asset.endsWith(".otf")) {
            try {
                return new WebResourceResponse("font/" + MimeTypeMap.getFileExtensionFromUrl(asset), "utf-8", context.getAssets().open(asset)); // this will produce MimeType like: font/ttf
            } catch (IOException e) {
                e.printStackTrace();
            }
       }
   }
}

此代码在Android 4.1-4.4中运行良好,但在Android 5.0中,此代码加载了js,但无法加载字体,我在webkit控制台中看到以下消息:

  

来自原产地的字体" asset://'已被阻止加载   跨源资源共享策略:No' Access-Control-Allow-Origin'   标头出现在请求的资源上。起源' null'是   因此不允许访问。

如何从Android 5.0上的资源加载字体?

1 个答案:

答案 0 :(得分:5)

您需要使用新的WebResourceResponse构造函数来设置HTTP标头以及截获的请求。

由于新构造函数仅在Lollipop中引入,因此请务必在运行时检查SDK版本。

InputStream inputStream = context.getAssets().open("fonts/myfontasset.ttf");
WebResourceResponse response = null;
String encoding= "UTF-8";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    int statusCode = 200;
    String reasonPhase = "OK";
    Map<String, String> responseHeaders = new HashMap<String, String>();
    responseHeaders.put("Access-Control-Allow-Origin","*");
    response = new WebResourceResponse("font/ttf", encoding, statusCode, reasonPhase, responseHeaders, inputStream);
} else {
    response = new WebResourceResponse("font/ttf", encoding, inputStream);
}

注意:您必须至少针对SDK Level 21构建。