diff --git a/app/src/main/java/io/legado/app/ui/main/MainActivity.kt b/app/src/main/java/io/legado/app/ui/main/MainActivity.kt index a417f4ca1..56b6e5715 100644 --- a/app/src/main/java/io/legado/app/ui/main/MainActivity.kt +++ b/app/src/main/java/io/legado/app/ui/main/MainActivity.kt @@ -64,6 +64,9 @@ class MainActivity : VMBaseActivity(R.layout.activity_main), viewModel.upChapterList() }, 1000) } + view_pager_main.postDelayed({ + viewModel.postLoad() + }, 3000) } override fun onNavigationItemSelected(item: MenuItem): Boolean { diff --git a/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt b/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt index b7392aaef..186f54a92 100644 --- a/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt @@ -10,6 +10,7 @@ import io.legado.app.data.entities.RssSource import io.legado.app.help.http.HttpHelper import io.legado.app.help.storage.Restore import io.legado.app.model.WebBook +import io.legado.app.utils.FileUtils import io.legado.app.utils.GSON import io.legado.app.utils.fromJsonObject import io.legado.app.utils.postEvent @@ -77,4 +78,14 @@ class MainViewModel(application: Application) : BaseViewModel(application) { } } } + + fun postLoad() { + execute { + FileUtils.getDirFile(context.cacheDir, "Fonts").let { + if (it.exists()) { + it.delete() + } + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/widget/font/FontAdapter.kt b/app/src/main/java/io/legado/app/ui/widget/font/FontAdapter.kt index ab6e34a1c..5e5655c44 100644 --- a/app/src/main/java/io/legado/app/ui/widget/font/FontAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/widget/font/FontAdapter.kt @@ -2,9 +2,12 @@ package io.legado.app.ui.widget.font import android.content.Context import android.graphics.Typeface +import android.os.Build import io.legado.app.R import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.SimpleRecyclerAdapter +import io.legado.app.utils.DocItem +import io.legado.app.utils.RealPathUtil import io.legado.app.utils.invisible import io.legado.app.utils.visible import kotlinx.android.synthetic.main.item_font.view.* @@ -13,12 +16,24 @@ import org.jetbrains.anko.toast import java.io.File class FontAdapter(context: Context, val callBack: CallBack) : - SimpleRecyclerAdapter(context, R.layout.item_font) { + SimpleRecyclerAdapter(context, R.layout.item_font) { - override fun convert(holder: ItemViewHolder, item: File, payloads: MutableList) { + override fun convert(holder: ItemViewHolder, item: DocItem, payloads: MutableList) { with(holder.itemView) { try { - val typeface = Typeface.createFromFile(item) + val typeface: Typeface? = if (item.isContentPath) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + context.contentResolver + .openFileDescriptor(item.uri, "r") + ?.fileDescriptor?.let { + Typeface.Builder(it).build() + } + } else { + Typeface.createFromFile(RealPathUtil.getPath(context, item.uri)) + } + } else { + Typeface.createFromFile(item.uri.toString()) + } tv_font.typeface = typeface } catch (e: Exception) { context.toast("读取${item.name}字体失败") @@ -42,7 +57,7 @@ class FontAdapter(context: Context, val callBack: CallBack) : } interface CallBack { - fun onClick(file: File) + fun onClick(docItem: DocItem) val curFilePath: String } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/widget/font/FontSelectDialog.kt b/app/src/main/java/io/legado/app/ui/widget/font/FontSelectDialog.kt index 8157ed870..34e629e33 100644 --- a/app/src/main/java/io/legado/app/ui/widget/font/FontSelectDialog.kt +++ b/app/src/main/java/io/legado/app/ui/widget/font/FontSelectDialog.kt @@ -26,11 +26,11 @@ import io.legado.app.ui.filechooser.FileChooserDialog import io.legado.app.ui.filechooser.FilePicker import io.legado.app.utils.* import kotlinx.android.synthetic.main.dialog_font_select.* -import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.File +import java.util.* class FontSelectDialog : BaseDialogFragment(), FileChooserDialog.CallBack, @@ -40,9 +40,6 @@ class FontSelectDialog : BaseDialogFragment(), private val fontFolder by lazy { FileUtils.createFolderIfNotExist(App.INSTANCE.filesDir, "Fonts") } - private val fontCacheFolder by lazy { - FileUtils.createFolderIfNotExist(App.INSTANCE.cacheDir, "Fonts") - } private var adapter: FontAdapter? = null override fun onStart() { @@ -90,7 +87,9 @@ class FontSelectDialog : BaseDialogFragment(), R.id.menu_default -> { val requireContext = requireContext() requireContext.alert(titleResource = R.string.system_typeface) { - items(requireContext.resources.getStringArray(R.array.system_typefaces).toList()) { _, i -> + items( + requireContext.resources.getStringArray(R.array.system_typefaces).toList() + ) { _, i -> AppConfig.systemTypefaces = i onDefaultFontChange() dismiss() @@ -117,40 +116,16 @@ class FontSelectDialog : BaseDialogFragment(), @SuppressLint("DefaultLocale") private fun getFontFiles(doc: DocumentFile) { execute { + val fontItems = arrayListOf() val docItems = DocumentUtils.listFiles(App.INSTANCE, doc.uri) - fontCacheFolder.listFiles()?.forEach { fontFile -> - var contain = false - for (item in docItems) { - if (fontFile.name == item.name) { - contain = true - break - } - } - if (!contain) { - fontFile.delete() - } - } docItems.forEach { item -> if (item.name.toLowerCase().matches(".*\\.[ot]tf".toRegex())) { - val fontFile = FileUtils.getFile(fontCacheFolder, item.name) - if (!fontFile.exists()) { - DocumentUtils.readBytes(App.INSTANCE, item.uri)?.let { byteArray -> - fontFile.writeBytes(byteArray) - } - } - } - } - try { - fontCacheFolder.listFiles { pathName -> - pathName.name.toLowerCase().matches(".*\\.[ot]tf".toRegex()) - }?.let { - withContext(Main) { - adapter?.setItems(it.toList()) - } + fontItems.add(item) } - } catch (e: Exception) { - toast(e.localizedMessage ?: "") } + fontItems + }.onSuccess { + adapter?.setItems(it) }.onError { toast("getFontFiles:${it.localizedMessage}") } @@ -163,12 +138,22 @@ class FontSelectDialog : BaseDialogFragment(), .rationale(R.string.tip_perm_request_storage) .onGranted { try { + val fontItems = arrayListOf() val file = File(path) file.listFiles { pathName -> pathName.name.toLowerCase().matches(".*\\.[ot]tf".toRegex()) - }?.let { - adapter?.setItems(it.toList()) + }?.forEach { + fontItems.add( + DocItem( + it.name, + it.extension, + it.length(), + Date(it.lastModified()), + Uri.parse(it.absolutePath) + ) + ) } + adapter?.setItems(fontItems) } catch (e: Exception) { toast(e.localizedMessage ?: "") } @@ -176,16 +161,32 @@ class FontSelectDialog : BaseDialogFragment(), .request() } - override fun onClick(file: File) { - launch(IO) { - file.copyTo(FileUtils.createFileIfNotExist(fontFolder, file.name), true) - .absolutePath.let { path -> - if (curFilePath != path) { - withContext(Main) { - callBack?.selectFile(path) + override fun onClick(docItem: DocItem) { + execute { + fontFolder.listFiles()?.forEach { + it.delete() + } + if (docItem.isContentPath) { + val file = FileUtils.createFileIfNotExist(fontFolder, docItem.name) + @Suppress("BlockingMethodInNonBlockingContext") + requireActivity().contentResolver.openInputStream(docItem.uri)?.use { input -> + file.outputStream().use { output -> + input.copyTo(output) } } + callBack?.selectFile(file.path) + } else { + val file = File(docItem.uri.toString()) + file.copyTo(FileUtils.createFileIfNotExist(fontFolder, file.name), true) + .absolutePath.let { path -> + if (curFilePath != path) { + withContext(Main) { + callBack?.selectFile(path) + } + } + } } + }.onSuccess { dialog?.dismiss() } } diff --git a/app/src/main/java/io/legado/app/utils/DocumentUtils.kt b/app/src/main/java/io/legado/app/utils/DocumentUtils.kt index b53cebb14..041189c7f 100644 --- a/app/src/main/java/io/legado/app/utils/DocumentUtils.kt +++ b/app/src/main/java/io/legado/app/utils/DocumentUtils.kt @@ -138,6 +138,8 @@ data class DocItem( val isDir: Boolean by lazy { DocumentsContract.Document.MIME_TYPE_DIR == attr } + + val isContentPath get() = uri.toString().isContentPath() } @Throws(Exception::class)