Intereting Posts
Android-разрешения GET_ACCOUNTS и USE_CREDENTIALS отображаются автоматически ? Android: attr / selectableItemBackground недостаточно заметен на темном фоне Две строки в тексте кнопки с разными размерами HttpResponse с использованием проблемы Android: выполнение всегда вызывает исключение? Есть ли хороший инструмент для разработки макета Android? Как отменить покупку in-app на Android? Android скрывает / скрывает значок приложения программно RecyclerView сохраняет / восстанавливает состояние между действиями Как я могу масштабировать текстовые изображения, используя общие переходы элементов? Выполнение сканирования UPNP не возвращает мост Philips Hue Изменение значений шагов в строке поиска? Привязать услугу к активности на Android Как возобновить работу медиаплеер? Как опубликовать приложение для планшетов только для Android с векторными чертежами EGL_emulation не удалось установить соединение с host-android

Android – восстановить имя строки системного шрифта по умолчанию

С некоторыми разновидностями Android (Samsung, LG, HTC), похоже, можно установить системный шрифт по умолчанию без укорачивания . У меня нет одного из этих устройств для тестирования (у меня есть старый планшет Lenovo), но мне интересно следующее:

  1. Метод Typeface.DEFAULT возвращает Typeface пользовательского шрифта на этих устройствах или всегда возвращает информацию о Roboto?
  2. Если он возвращает информацию о пользовательском Typeface, как я могу программным образом получить имя (строку) шрифта пользовательского Typeface?
  3. Если Typeface.DEFAULT является тупиком, есть ли другой способ получить имя по умолчанию для системного шрифта? Может быть, выкачать файлы TTF?

EDIT: Я добавляю способ, который, как я думал, может работать, но на самом деле это не так: сравнение Typeface.DEFAULT с объектами Typeface, созданными из файлов в каталогах /system/fonts , /system/font и /data/fonts . Это не ответ, но это может помочь кому-то придумать. Также обратите внимание, что класс TTFAnalyzer не мой. Код следует:

 private String getDefaultFont() { String[] fontdirs = { "/system/fonts", "/system/font", "/data/fonts" }; TTFAnalyzer analyzer = new TTFAnalyzer(); Typeface tfDefault = Typeface.DEFAULT; Typeface tfTemp = null; String defaultFontName = ""; System.out.println("getDefaultFont(): entry"); System.out.println("tfDefault: " + tfDefault.toString()); for ( String fontdir : fontdirs ) { File dir = new File( fontdir ); if ( !dir.exists() ) continue; File[] files = dir.listFiles(); if ( files == null ) continue; for ( File file : files ) { String fontname = analyzer.getTtfFontName( file.getAbsolutePath() ); if ( fontname != null ) { System.out.println("found font: " + fontname); tfTemp = Typeface.createFromFile(file); System.out.println("tfTemp: " + tfTemp.toString()); //** THIS SHOULD BE WORKING? **// if (tfTemp.equals(tfDefault)) { System.out.println("Found default font: " + fontname); defaultFontName = fontname; } } } } return defaultFontName; } // The class which loads the TTF file, parses it and returns the TTF font name class TTFAnalyzer { // This function parses the TTF file and returns the font name specified in the file public String getTtfFontName( String fontFilename ) { try { // Parses the TTF file format. // See http://developer.apple.com/fonts/ttrefman/rm06/Chap6.html m_file = new RandomAccessFile( fontFilename, "r" ); // Read the version first int version = readDword(); // The version must be either 'true' (0x74727565) or 0x00010000 if ( version != 0x74727565 && version != 0x00010000 ) return null; // The TTF file consist of several sections called "tables", and we need to know how many of them are there. int numTables = readWord(); // Skip the rest in the header readWord(); // skip searchRange readWord(); // skip entrySelector readWord(); // skip rangeShift // Now we can read the tables for ( int i = 0; i < numTables; i++ ) { // Read the table entry int tag = readDword(); readDword(); // skip checksum int offset = readDword(); int length = readDword(); // Now here' the trick. 'name' field actually contains the textual string name. // So the 'name' string in characters equals to 0x6E616D65 if ( tag == 0x6E616D65 ) { // Here's the name section. Read it completely into the allocated buffer byte[] table = new byte[ length ]; m_file.seek( offset ); read( table ); // This is also a table. See http://developer.apple.com/fonts/ttrefman/rm06/Chap6name.html // According to Table 36, the total number of table records is stored in the second word, at the offset 2. // Getting the count and string offset - remembering it's big endian. int count = getWord( table, 2 ); int string_offset = getWord( table, 4 ); // Record starts from offset 6 for ( int record = 0; record < count; record++ ) { // Table 37 tells us that each record is 6 words -> 12 bytes, and that the nameID is 4th word so its offset is 6. // We also need to account for the first 6 bytes of the header above (Table 36), so... int nameid_offset = record * 12 + 6; int platformID = getWord( table, nameid_offset ); int nameid_value = getWord( table, nameid_offset + 6 ); // Table 42 lists the valid name Identifiers. We're interested in 4 but not in Unicode encoding (for simplicity). // The encoding is stored as PlatformID and we're interested in Mac encoding if ( nameid_value == 4 && platformID == 1 ) { // We need the string offset and length, which are the word 6 and 5 respectively int name_length = getWord( table, nameid_offset + 8 ); int name_offset = getWord( table, nameid_offset + 10 ); // The real name string offset is calculated by adding the string_offset name_offset = name_offset + string_offset; // Make sure it is inside the array if ( name_offset >= 0 && name_offset + name_length < table.length ) return new String( table, name_offset, name_length ); } } } } return null; } catch (FileNotFoundException e) { // Permissions? return null; } catch (IOException e) { // Most likely a corrupted font file return null; } } // Font file; must be seekable private RandomAccessFile m_file = null; // Helper I/O functions private int readByte() throws IOException { return m_file.read() & 0xFF; } private int readWord() throws IOException { int b1 = readByte(); int b2 = readByte(); return b1 << 8 | b2; } private int readDword() throws IOException { int b1 = readByte(); int b2 = readByte(); int b3 = readByte(); int b4 = readByte(); return b1 << 24 | b2 << 16 | b3 << 8 | b4; } private void read( byte [] array ) throws IOException { if ( m_file.read( array ) != array.length ) throw new IOException(); } // Helper private int getWord( byte [] array, int offset ) { int b1 = array[ offset ] & 0xFF; int b2 = array[ offset + 1 ] & 0xFF; return b1 << 8 | b2; } } 

РЕДАКТИРОВАТЬ 2: еще немного информации о том, что ты купишь мой планшет Lenovo. В /system/etc есть несколько интересных XML-файлов:

  • system_fonts.xml – похоже, что он имеет шрифты по умолчанию для регулярного / курсивного / полужирного шрифта в качестве первой записи семейства
  • fallback_fonts.xml – у которого есть шрифты, которые Android должен отступить, если он не может найти глиф в текущем шрифте (например, тайские символы).

Возможно, стоит разобрать этот файл system_fonts и вернуть имя шрифта по умолчанию, но я не знаю, правильно ли это сделать.

Solutions Collecting From Web of "Android – восстановить имя строки системного шрифта по умолчанию"

Хорошо, вот что я думаю, что работает. Что касается одобрения Android, ну, это хакки. Это решение предполагает несколько вещей:

  • Файл /system/etc/system_fonts.xml содержит список шрифтов на устройстве.
  • Первый элемент <file> в этом файле system_fonts.xml является шрифтом по умолчанию для устройства.
  • Шрифт по умолчанию расположен в /system/fonts .

Эти предположения связаны с просмотром файла класса Typeface с Android 5.x, но я тестировал еще пару других версий, и решение, похоже, тоже работает там. Код следует (при условии, что класс TTFAnalyzer, указанный выше):

 import android.util.Xml; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; public String getDefaultFont() { System.out.println("getFontList(): entry"); File configFilename = new File("/system/etc/system_fonts.xml"); String defaultFontName = ""; TTFAnalyzer analyzer = new TTFAnalyzer(); try { FileInputStream fontsIn = new FileInputStream(configFilename); XmlPullParser parser = Xml.newPullParser(); parser.setInput(fontsIn, null); Boolean done = false; Boolean getTheText = false; int eventType; String defaultFont = ""; while (!done) { eventType = parser.next(); if (eventType == parser.START_TAG && parser.getName().equalsIgnoreCase("file")) { // the text is next up -- pull it getTheText = true; } if (eventType == parser.TEXT && getTheText == true) { // first name defaultFont = parser.getText(); System.out.println("text for file tag:" + defaultFont); done = true; } if (eventType == parser.END_DOCUMENT) { System.out.println("hit end of system_fonts.xml document"); done = true; } } if (defaultFont.length() > 0) { // found the font filename, most likely in /system/fonts. Now pull out the human-readable // string from the font file System.out.println("Figuring out default Font info"); String fontname = analyzer.getTtfFontName("/system/fonts/" + defaultFont); if ( fontname != null ) { System.out.println("found font info: " + fontname); defaultFontName = fontname; } } } catch (RuntimeException e) { System.err.println("Didn't create default family (most likely, non-Minikin build)"); // TODO: normal in non-Minikin case, remove or make error when Minikin-only } catch (FileNotFoundException e) { System.err.println("GetDefaultFont: config file Not found"); } catch (IOException e) { System.err.println("GetDefaultFont: IO exception: " + e.getMessage()); } catch (XmlPullParserException e) { System.err.println("getDefaultFont: XML parse exception " + e.getMessage()); } return defaultFontName; } 
  String fontName=Typeface.Default; 

Это вернет имя шрифта в строке

  Typeface.defaultFromStyle(int style). 

Возвращает шрифт из определенного стиля.

https://developer.android.com/reference/android/graphics/Typeface.html