Robert
Robert

Reputation: 2389

Android assets retrieve embedded font for Typeface

I've managed to embed a font which I can access through Typeface.createFromAsset, however, there is also the "file:///android_asset/.." protocol.

I tried using "file:///android_asset/fonts/myfont.ttf" for Typeface.createFromFile, but this does not work ? Strange as I would have thought that file:///android_asset is handled by the system and thus Typeface would be able to get an InputStream ?

So my specific question is: Why doesn't the file:///android_asset/ protocol work with Typeface.createFromFile ?

Upvotes: 0

Views: 561

Answers (2)

Robert
Robert

Reputation: 2389

The solution I opted for was to write a binary array into a cache file, then use Typeface.createFromFile(path) with the cache file.

The solution looks like this:

final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();

public static String bytesToHex (byte[] bytes)
{
    char[] hexChars = new char[bytes.length * 2];

    for (int j = 0; j < bytes.length; ++j)
    {
        int v = bytes[j] & 0xff;
        hexChars[j * 2]     = hexArray[v >>> 4];
        hexChars[j * 2 + 1] = hexArray[v & 0x0f];
    }

    return new String (hexChars);
}

final private java.util.Map dataCache = new java.util.HashMap();

synchronized private final File getDataCacheFile (byte[] data)
{
    try
    {
        java.security.MessageDigest digest = java.security.MessageDigest.getInstance ("MD5");
        digest.update (data);

        String key = bytesToHex (digest.digest());

        if (dataCache.containsKey (key))
            return (File) dataCache.get (key);

        File f = new File (this.getCacheDir(), "bindata_" + key);
        f.delete();
        FileOutputStream os = new FileOutputStream (f);
        os.write (data, 0, data.length);
        dataCache.put (key, f);
        return f;
    }
    catch (Throwable e) {}

    return null;
}

private final void clearDataCache()
{
    java.util.Iterator it = dataCache.values().iterator();

    while (it.hasNext())
    {
        File f = (File) it.next();
        f.delete();
    }
}

public final Typeface getTypeFaceFromByteArray (byte[] data)
{
    try
    {
        File f = getDataCacheFile (data);

        if (f != null)
            return Typeface.createFromFile (f);
    }
    catch (Exception e)
    {
        Log.e ("<tag>", e.toString());
    }

    return null;
}

Upvotes: 0

Chandrakanth
Chandrakanth

Reputation: 3831

To Typeface.createFromFile(path) method you have to pass the path which is related to the device you are running the app. So this method will look for the font file in the device directory but not in the asset folder. If you give the path like file:///android_asset/ protocol then it will not found the device file system. So it will not works.

Upvotes: 1

Related Questions