At the follow link
Android Dev Guide
is write:
Library projects cannot include raw assets The tools do not support the use of raw asset files (saved in t
Here's a method for loading fonts from resources that actually works ;-) Credit to mr32bit for the first version.
private Typeface getFontFromRes(int resource)
{
Typeface tf = null;
InputStream is = null;
try {
is = getResources().openRawResource(resource);
}
catch(NotFoundException e) {
Log.e(TAG, "Could not find font in resources!");
}
String outPath = getCacheDir() + "/tmp" + System.currentTimeMillis() ".raw";
try
{
byte[] buffer = new byte[is.available()];
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(outPath));
int l = 0;
while((l = is.read(buffer)) > 0)
bos.write(buffer, 0, l);
bos.close();
tf = Typeface.createFromFile(outPath);
// clean up
new File(outPath).delete();
}
catch (IOException e)
{
Log.e(TAG, "Error reading in font!");
return null;
}
Log.d(TAG, "Successfully loaded font.");
return tf;
}
Even though You put Your fonts in assets/fonts folder, somehow this library works and its very easy to use: https://github.com/neopixl/PixlUI . I've successfully tested it on Android 2.3. as well as 4.4
The code below modifies the solution from @bk138 and includes @Jason Robinson recommendations for not deleting the file and checking for a previously cached file first. Also, it names the temp file after the font instead of the time created.
public static Typeface getFontFromRes(Context context, int resId, boolean deleteAfterwards){
String tag = "StorageUtils.getFontFromRes";
String resEntryName = context.getResources().getResourceEntryName(resId);
String outPath = context.getCacheDir() + "/tmp_" + resEntryName + ".raw";
//First see if the file already exists in the cachDir
FileInputStream fis = null;
try {
fis = new FileInputStream(new File(outPath));
} catch (FileNotFoundException e) {
Log.d(tag,"fileNotFoundException outPath:"+outPath+e.getMessage());
}
if(fis != null){
try {
Log.d(tag,"found cached fontName:"+resEntryName);
fis.close();
} catch (IOException e) {
Log.d(tag,"IOException outPath:"+outPath+e.getMessage());
}
//File is already cached so return it now
return Typeface.createFromFile(outPath);
}
InputStream is = null;
try {
is = context.getResources().openRawResource(resId);
}catch(NotFoundException e) {
Log.e(tag, "Could not find font in resources! " + outPath);
}
try{
byte[] buffer = new byte[is.available()];
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(outPath));
int l = 0;
while((l = is.read(buffer)) > 0)
bos.write(buffer, 0, l);
bos.close();
}catch (IOException e){
Log.e(tag, "Error reading in font!");
return null;
}
Typeface tf = Typeface.createFromFile(outPath);
if(deleteAfterwards){
// clean up if desired
new File(outPath).delete();
}
Log.d(tag, "Successfully loaded font.");
return tf;
}
Just use the response of @bk138 with this little change it works to me
add this in the manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
and add this before creating the Buffered
File f2 = new File(outPath);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(outPath));
If you extend a TextView and want to use many of this views you should have only one instance of the Typeface in this view. Copy the *.ttf file into res/raw/ and use the following code:
public class MyTextView extends TextView {
public static final String FONT = "font.ttf";
private static Typeface mFont;
private static Typeface getTypefaceFromFile(Context context) {
if(mFont == null) {
File font = new File(context.getFilesDir(), FONT);
if (!font.exists()) {
copyFontToInternalStorage(context, font);
}
mFont = Typeface.createFromFile(font);
}
return mFont;
}
private static void copyFontToInternalStorage(Context context, File font) {
try {
InputStream is = context.getResources().openRawResource(R.raw.font);
byte[] buffer = new byte[4096];
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(font));
int readByte;
while ((readByte = is.read(buffer)) > 0) {
bos.write(buffer, 0, readByte);
}
bos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
setTypeface(getTypefaceFromFile(context));
}
}
mFont is a static variable, so the reference will not be destroyed and can be reused in other MyTextViews. This code is nearly the same as the other answers but I guess mor efficient and consumes less memory if you are using it in a ListView or something.
Ok I have found a workaround for the problem. You need to copy the file to an external directory then load a typeface from file with Typeface.createFromFile
and then delete the temporary file. I know is not a clean mode of work but is working grate.
1 - You need to put your font on "/res/raw/font.ttf"
2 - Inser in your code the following method
3 - put in your code Typeface mFont = FileStreamTypeface(R.raw.font);
4 - All is done
Typeface FileStreamTypeface(int resource)
{
Typeface tf = null;
InputStream is = getResources().openRawResource(resource);
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/gmg_underground_tmp";
File f = new File(path);
if (!f.exists())
{
if (!f.mkdirs())
return null;
}
String outPath = path + "/tmp.raw";
try
{
byte[] buffer = new byte[is.available()];
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(outPath));
int l = 0;
while((l = is.read(buffer)) > 0)
{
bos.write(buffer, 0, l);
}
bos.close();
tf = Typeface.createFromFile(outPath);
File f2 = new File(outPath);
f2.delete();
}
catch (IOException e)
{
return null;
}
return tf;
}
if someone have an alternative I'm pleased to read it. Do you have to remember that this workaround is only for Android Libraries
Best regards