Как можно использовать шрифт, который находится в файлах пользователя?

Как мне использовать шрифт из пользовательской папки, например, /Fonts/font.ttf, и применить его к View? Я пытаюсь сделать это с помощью Typeface.createFromFile, но результат не удается. Вот мой код: <br/> <pre><code>binding.clock.typeface = Typeface.createFromFile(Environment.getExternalStorageDirectory().path + "/Fonts/AdventPro-Regular.ttf")</code></pre> <br/> Также в AndroidManifest.xml я добавил следующую строку: <br/> <pre><code>&lt;uses-permission
        android:name="android.permission.READ_EXTERNAL_STORAGE"
        tools:ignore="ScopedStorage" /&gt;</code></pre> <br/> Могли бы вы помочь разобраться в этой проблеме?
  • 25 сентября 2024 г. 6:53
Ответы на вопрос 3
Для того чтобы использовать шрифт из пользовательской папки в Android-приложении, важно учитывать несколько моментов:

1. **Права доступа**: Убедитесь, что ваше приложение имеет права на чтение внешнего хранилища, что вы уже сделали, добавив разрешение `READ_EXTERNAL_STORAGE` в манифест. Однако начиная с Android 10 (API 29) доступны изменения в политике безопасности, которые могут потребовать дополнительных действий, таких как использование Scoped Storage.

2. **Проверка наличия файла**: Прежде чем пытаться загрузить шрифт, убедитесь, что файл на самом деле существует по указанному пути.

3. **Использование `Typeface.createFromFile`**: Этот метод должен работать при корректно заданном пути. Для начала проверьте, помогает ли добавить `file://` перед путем к файлу.

Вот пример того, как вы могли бы это реализовать:

```kotlin
import android.graphics.Typeface
import android.os.Bundle
import android.os.Environment
import android.util.Log
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Получаем путь к шрифту
        val fontPath = Environment.getExternalStorageDirectory().path + "/Fonts/AdventPro-Regular.ttf"

        // Проверяем, существует ли файл
        val fontFile = File(fontPath)
        if (fontFile.exists()) {
            // Применяем шрифт к TextView
            val typeface = Typeface.createFromFile(fontFile)
            binding.clock.typeface = typeface
        } else {
            Log.e("FontError", "Файл шрифта не найден: $fontPath")
        }
    }
}
```

Не забудьте добавить проверки разрешений по запросу, особенно для устройств на Android 6.0 (API 23) и выше:

```kotlin
private fun checkPermission() {
    if (ContextCompat.checkSelfPermission(this, 
        Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
        
        ActivityCompat.requestPermissions(this, 
            arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), 1)
    }
}
```

Также, если ваше приложение нацелено на Android 10 и выше, возможно, вам придется использовать более современные подходы к доступу к файлам, такие как `Scoped Storage`. В данном случае, возможно, вам будет удобнее хранить шрифты в папке вашего приложения или использовать ресурсы вашего приложения (`res/font`).

### Примечание:
Использование внешнего хранилища может быть рискованным, и лучше хранить шрифты в папке `assets` вашего приложения или в ресурсе `res/font`, если это возможно. Это упростит управление шрифтами и избежит проблем с доступом к файлам.
1. ```Environment.getExternalStorageDirectory().path``` вы уверены, что так правильно? Что-то я не вижу поля path в классе File. Рекомендуют всё-такие вот так: ```Environment.getExternalStorageDirectory().getAbsolutePath()``` 

2. Но даже это не избавляет вас от обязательств прооверять наличие файла перед его использованием.
permission.READ_EXTERNAL_STORAGE - табу / красная тряпка для модерации 
считается что приложения должны работать со своими файлами в песочнице -
своих папках КЕШ (можно удалить при нехватке места на телефоне) и ФАЙЛЫ (равнозначно новой установке)

Зашить файл в дистрибутив можно через Raw ресурсы или через Assets.
Можно включить(преднаселить) минимум, а остальное нужное скачивать по запросу.

Но применительно к шрифтам можно взять готовое решение для Google Fonts
https://developers.google.com/fonts/docs/android?hl=ru
Похожие вопросы