How to set FontFamily for a WebView with Downloadable Fonts?

506 Views Asked by At

I currently refactored my app to use Downloadable Fonts hence I don't have any asset files for fonts. I have searched a lot and the only solution I see is to set the FontFamily in a CSS file and point the src to assets folder. This is not possible with downloadable fonts.

1

There are 1 best solutions below

0
Maran Subburayan On

When using Android Downloadable Font, You can get the URI of the ttf font file from the FontInfo.getUri() method.

FontsContractCompat.FontFamilyResult fontFamilyResult = FontsContractCompat.fetchFonts(view.getContext(), null, fontRequest);
Uri fontUri = fontFamilyResult.getFonts()[0].getUri();

You can use this URI to cache the ttf file in your app space which you can directly refer in WebView HTML and other places.

If you want to use the URI model instead, note that you can't directly use the URI returned by FontsContractCompat because it may violate CORS policy due to different base domains of the loaded content and this URI. You can use a custom URI pattern in the WebView HTML and intercept that request in WebViewClient's shouldInterceptRequest method where you can return an InputStream ( wrapped as WebResourceResponse ) from the URI returned by FontsContractCompat query or locally cached font file.

form the URI in css like this ( requires setting myappscheme://com.myapp.demo as base url of your content )

@font-face {
  font-family: Roboto;
  src: url('myappscheme://com.myapp.demo/fonts/name=Roboto');
}

and in WebViewClient. this is just a demo code snippet. so throw in some error handling here

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request)
    {
        Uri requestUri = request.getUrl();
        if (requestUri.getScheme()
                      .equals("myappscheme") && requestUri.getPath()
                                                          .startsWith("fonts"))
        {
            Context context = view.getContext();
            File fontFile = new File(context.getExternalCacheDir(), requestUri.getQueryParameter("name") + ".ttf");
            if (!fontFile.exists())
            {
                FontRequest fontRequest = new FontRequest(
                    "com.google.android.gms.fonts",
                    "com.google.android.gms",
                    requestUri.getQuery(),
                    R.array.com_google_android_gms_fonts_certs);

                FontsContractCompat.FontFamilyResult fontFamilyResult = FontsContractCompat.fetchFonts(view.getContext(), null, fontRequest);
                if (fontFamilyResult.getStatusCode() == FontsContractCompat.FontFamilyResult.STATUS_OK)
                {
                    InputStream gFont = context.getContentResolver()
                                               .openInputStream(fontFamilyResult.getFonts()[0].getUri());
                    fontFile.createNewFile();
                    ByteStreamsKt.copyTo(gFont, new FileOutputStream(fontFile), 4096);
                }
            }
            return new WebResourceResponse("application/octet-stream", null, new FileInputStream(fontFile));
        }
    }