ZOFTINO.COM android and web dev tutorials

Downloading Fonts Android

To make an android application use fonts from font providers, font files are included in android app APK or APK is made to download font files from font providers. With android 8.0 (API 26) and support library 26, you no longer need to include fonts in APK files, instead you can use API to request fonts from font providers.

With downloadable fonts API, APK file gets reduced because font files are not required to be included in APK file and all the apps on a device can share fonts using font provider without needing to download the same font multiple times for each app.

Downloadable Font Feature Support

If you want downloadable font feature on devices running on versions prior to Android 8.0 (API 26), you can use support library. Android support library version 26 supports downloadable font, to use it, you need to add below support library entry to dependencies section in your project build.gradle file.

compile 'com.android.support:support-compat:26.0.1'

Font Provider

Font provider is an app which downloads requested fonts and caches it so that next font request of same font type is served from cache instead of downloading. In order for downloadable font to work, font provider app needs to be installed on device. If font provider app is not installed on a device or downloading of fonts fails, default font is used.

Google provides font provider app and it is part of Google play service. Google font provider is available with Google play service version 11 and higher.

Making App Download Fonts by Defining Downloadable Fonts in XML

With new feature in android 8.0 (API 26), fonts can be defined in xml as resources. This feature can be used to define downloadable fonts and use it in layouts.

Again, here are we are using two new features introduced in android 8.0 to define custom fonts for our example android app. One is the capability to define fonts as resources in xml and second feature that allows fonts to be download from font provider instead of including them in the APK files.

Below are the steps to use downloadable fonts.

Defining font in XML

First define font in xml and place the file in res/font folder. Font xml’s root element is font-family. Font-family element has attributes such as fontProviderAuthority, fontProviderPackage, fontProviderQuery and fontProviderCerts to set provider, provider certificatate and font query information. Attribute fontProviderQuery can be used to set font name, style and weight. Since Google play service font provider supports Google fonts, set fontProviderQuery value to one of Google font names.

Below is the configuration to use Google play service as font provider.

<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:app="http://schemas.android.com/apk/res-auto"
    app:fontProviderAuthority="com.google.android.gms.fonts"
    app:fontProviderPackage="com.google.android.gms"
    app:fontProviderQuery="Pacifico"
    app:fontProviderCerts="@array/google_fonts_certs" />
 

Adding font provider certificates

Next, font provider certificates need to be added to project by defining certificate as string resource and placing it in res/values. Below certificates are for Google play service dev and prod environment and they can be used as it is if you are planning to use Google play service as font provider.

This certificates file is referred to in font file using fontProviderCerts attribute, see above font file.

 <?xml version="1.0" encoding="utf-8"?>
<resources>
    <array name="google_fonts_certs">
        <item>@array/google_fonts_certs_dev</item>
        <item>@array/google_fonts_certs_prod</item>
    </array>
    <string-array name="google_fonts_certs_dev">
        <item>
            MIIEqDCCA5CgAwIBAgIJANWFuGx90071MA0GCSqGSIb3DQEBBAUAMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAeFw0wODA0MTUyMzM2NTZaFw0zNTA5MDEyMzM2NTZaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgCggEBANbOLggKv+IxTdGNs8/TGFy0PTP6DHThvbbR24kT9ixcOd9W+EaBPWW+wPPKQmsHxajtWjmQwWfna8mZuSeJS48LIgAZlKkpFeVyxW0qMBujb8X8ETrWy550NaFtI6t9+u7hZeTfHwqNvacKhp1RbE6dBRGWynwMVX8XW8N1+UjFaq6GCJukT4qmpN2afb8sCjUigq0GuMwYXrFVee74bQgLHWGJwPmvmLHC69EH6kWr22ijx4OKXlSIx2xT1AsSHee70w5iDBiK4aph27yH3TxkXy9V89TDdexAcKk/cVHYNnDBapcavl7y0RiQ4biu8ymM8Ga/nmzhRKya6G0cGw8CAQOjgfwwgfkwHQYDVR0OBBYEFI0cxb6VTEM8YYY6FbBMvAPyT+CyMIHJBgNVHSMEgcEwgb6AFI0cxb6VTEM8YYY6FbBMvAPyT+CyoYGapIGXMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbYIJANWFuGx90071MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADggEBABnTDPEF+3iSP0wNfdIjIz1AlnrPzgAIHVvXxunW7SBrDhEglQZBbKJEk5kT0mtKoOD1JMrSu1xuTKEBahWRbqHsXclaXjoBADb0kkjVEJu/Lh5hgYZnOjvlba8Ld7HCKePCVePoTJBdI4fvugnL8TsgK05aIskyY0hKI9L8KfqfGTl1lzOv2KoWD0KWwtAWPoGChZxmQ+nBli+gwYMzM1vAkP+aayLe0a1EQimlOalO762r0GXO0ks+UeXde2Z4e+8S/pf7pITEI/tP+MxJTALw9QUWEv9lKTk+jkbqxbsh8nfBUapfKqYn0eidpwq2AzVp3juYl7//fKnaPhJD9gs=
        </item>
    </string-array>
    <string-array name="google_fonts_certs_prod">
        <item>
            MIIEQzCCAyugAwIBAgIJAMLgh0ZkSjCNMA0GCSqGSIb3DQEBBAUAMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDAeFw0wODA4MjEyMzEzMzRaFw0zNjAxMDcyMzEzMzRaMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgCggEBAKtWLgDYO6IIrgqWbxJOKdoR8qtW0I9Y4sypEwPpt1TTcvZApxsdyxMJZ2JORland2qSGT2y5b+3JKkedxiLDmpHpDsz2WCbdxgxRczfey5YZnTJ4VZbH0xqWVW/8lGmPav5xVwnIiJS6HXk+BVKZF+JcWjAsb/GEuq/eFdpuzSqeYTcfi6idkyugwfYwXFU1+5fZKUaRKYCwkkFQVfcAs1fXA5V+++FGfvjJ/CxURaSxaBvGdGDhfXE28LWuT9ozCl5xw4Yq5OGazvV24mZVSoOO0yZ31j7kYvtwYK6NeADwbSxDdJEqO4k//0zOHKrUiGYXtqw/A0LFFtqoZKFjnkCAQOjgdkwgdYwHQYDVR0OBBYEFMd9jMIhF1Ylmn/Tgt9r45jk14alMIGmBgNVHSMEgZ4wgZuAFMd9jMIhF1Ylmn/Tgt9r45jk14aloXikdjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLR29vZ2xlIEluYy4xEDAOBgNVBAsTB0FuZHJvaWQxEDAOBgNVBAMTB0FuZHJvaWSCCQDC4IdGZEowjTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4IBAQBt0lLO74UwLDYKqs6Tm8/yzKkEu116FmH4rkaymUIE0P9KaMftGlMexFlaYjzmB2OxZyl6euNXEsQH8gjwyxCUKRJNexBiGcCEyj6z+a1fuHHvkiaai+KL8W1EyNmgjmyy8AW7P+LLlkR+ho5zEHatRbM/YAnqGcFh5iZBqpknHf1SKMXFh4dd239FJ1jWYfbMDMy3NS5CTMQ2XFI1MvcyUTdZPErjQfTbQe3aDQsQcafEQPD+nqActifKZ0Np0IS9L9kR/wbNvyz6ENwPiTrjV2KRkEjH78ZMcUQXg0L3BYHJ3lc69Vs5Ddf9uUGGMYldX3WfMBEmh/9iFBDAaTCK
        </item>
    </string-array>
</resources>

Using downloadable font on TextView

You can use the defined font directly in layout or to define styles. Below example shows using the downloadable font on TextView by setting fontFamily attribute to the defined font.

 <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.srinu.downloadablefonts.MainActivity">

    <TextView
        android:id="@+id/textView2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:layout_marginTop="24dp"
        android:fontFamily="@font/awesome_font"
        android:text="@string/test_txt"
        android:textSize="25dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:layout_marginTop="8dp"
        android:fontFamily="@font/best_font"
        android:text="@string/test_txt"
        android:textSize="25dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView2" />

</android.support.constraint.ConstraintLayout>
 

Pre declaring fonts or avoiding delay in first-time layout due to downloading of fonts

When you use downloadable fonts in your app, required font files are downloaded from font provider when app is used first time after installation on a device leading to delay in first time layout.

To avoid first time layout delay, fonts can be pre-declared in manifest file as shown below. Pre-declaring fonts involves creating array of fonts resource in res/values folder and then adding meta tag to manifest file.

Font resource array.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <array name="preloaded_fonts">
        <item>@font/best_font</item>
        <item>@font/awesome_font</item>
    </array>
</resources>

Meta tag in manifest.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.srinu.downloadablefonts">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
   	...............
	...............
        </activity>

        <meta-data android:name="preloaded_fonts" 
		android:resource="@array/preloaded_fonts" />

    </application>
</manifest>

Downloadable fonts example output

android downloadable fonts

Setting up Downloadable Fonts Using Android Studio

The above steps to configure downloadable fonts are performed manually. Using android studio, you can setup downloadable fonts easily by following below steps and Android Studio creates font files and certificate files for Google play service as font provider.

Below are the steps to set up downloadable fonts using Android Studio.

  1. Open layout file.
  2. Select TextField in design tab
  3. In the properties window, expand textAppearance if it not already expanded, then select fontFamily dropdown and click more fonts.
  4. Font resources window opens and displays Android and downloadable fonts sections.
  5. Select one of the downloadable fonts and click ok.
  6. Android studio will create font file in res/font folder, certificate file in res/values folder and font array resource file for pre-declaring fonts and adds meta tag related to pre-declaring fonts in manifest file.

Below is the screen shot of downloadable font setup in Android studio.

android studio downloadable fonts

Making App Download Fonts Programmatically

We have see how to use downloadable fonts by defining fonts in xml as resources. Application can be made to download and use fonts programmatically using FontRequest and FontsContract classes. You can use classes from support library 26 to make downloadable fonts work on devices running on versions prior to android 28.

Below are the steps to use downloadable fonts programmatically.

1. Instantiate FontRequest object passing font provider information and font query.

FontRequest fontRequest = new FontRequest("com.google.android.gms.fonts",
		"com.google.android.gms", "Finger Paint", R.array.google_fonts_certs);

2. Implement callback methods of FontRequestCallback, inner class of FontsContract, to handle font download completion or error notifications.

FontsContractCompat.FontRequestCallback fontRequestCallback =
     new FontsContractCompat.FontRequestCallback() {
        @Override
        public void onTypefaceRetrieved(Typeface typeface) {
	List<String> lst= null;
            programmaticallyDownloadableFontTextView.setTypeface(typeface);
        }
	@Override
        public void onTypefaceRequestFailed(int reason) {
            Toast.makeText(MainActivity.this,
                  "Failed download font programmatically", Toast.LENGTH_LONG)
                        .show();
        }
     }

3. Send font request calling requestFont method of FontsContract. We can use utility class FontsContractCompat to avoid writing boiler plate code.

FontsContractCompat.requestFont(this, fontRequest, fontRequestCallback , getThreadHandler());

4. Callback method onTypefaceRetrieved of FontRequestCallback is called on retrieving font from font provider. You can use Typeface on text fields.

 public void onTypefaceRetrieved(Typeface typeface) {
    programmaticallyDownloadableFontTextView.setTypeface(typeface);
}

You can download complete example from github at https://github.com/srinurp/DownloadableFonts.