diff --git a/app/src/main/java/io/legado/app/help/BookHelp.kt b/app/src/main/java/io/legado/app/help/BookHelp.kt index 617828374..ffd226137 100644 --- a/app/src/main/java/io/legado/app/help/BookHelp.kt +++ b/app/src/main/java/io/legado/app/help/BookHelp.kt @@ -48,7 +48,7 @@ object BookHelp { appDb.bookDao.all.forEach { bookFolderNames.add(it.getFolderName()) } - val file = FileUtils.getFile(downloadDir, cacheFolderName) + val file = downloadDir.getFile(cacheFolderName) file.listFiles()?.forEach { bookFile -> if (!bookFolderNames.contains(bookFile.name)) { FileUtils.deleteFile(bookFile.absolutePath) @@ -58,12 +58,7 @@ object BookHelp { } fun getEpubFile(book: Book): File { - val file = FileUtils.getFile( - downloadDir, - cacheFolderName, - book.getFolderName(), - "index.epubx" - ) + val file = downloadDir.getFile(cacheFolderName, book.getFolderName(), "index.epubx") if (!file.exists()) { val input = if (book.bookUrl.isContentScheme()) { val uri = Uri.parse(book.bookUrl) @@ -133,8 +128,7 @@ object BookHelp { } fun getImage(book: Book, src: String): File { - return FileUtils.getFile( - downloadDir, + return downloadDir.getFile( cacheFolderName, book.getFolderName(), cacheImageFolderName, @@ -171,8 +165,7 @@ object BookHelp { return if (book.isLocalTxt()) { true } else { - FileUtils.exists( - downloadDir, + downloadDir.exists( cacheFolderName, book.getFolderName(), bookChapter.getFileName() @@ -219,8 +212,7 @@ object BookHelp { } return string } else { - val file = FileUtils.getFile( - downloadDir, + val file = downloadDir.getFile( cacheFolderName, book.getFolderName(), bookChapter.getFileName() @@ -237,8 +229,7 @@ object BookHelp { */ fun reverseContent(book: Book, bookChapter: BookChapter) { if (!book.isLocalBook()) { - val file = FileUtils.getFile( - downloadDir, + val file = downloadDir.getFile( cacheFolderName, book.getFolderName(), bookChapter.getFileName() diff --git a/app/src/main/java/io/legado/app/help/CrashHandler.kt b/app/src/main/java/io/legado/app/help/CrashHandler.kt index 7d5161298..5d6ff64e7 100644 --- a/app/src/main/java/io/legado/app/help/CrashHandler.kt +++ b/app/src/main/java/io/legado/app/help/CrashHandler.kt @@ -7,6 +7,7 @@ import android.util.Log import io.legado.app.constant.AppConst import io.legado.app.model.ReadAloud import io.legado.app.utils.FileUtils +import io.legado.app.utils.getFile import io.legado.app.utils.longToastOnUi import io.legado.app.utils.msg import java.io.PrintWriter @@ -113,7 +114,7 @@ class CrashHandler(val context: Context) : Thread.UncaughtExceptionHandler { val time = format.format(Date()) val fileName = "crash-$time-$timestamp.log" context.externalCacheDir?.let { rootFile -> - FileUtils.getFile(rootFile, "crash").listFiles()?.forEach { + rootFile.getFile("crash").listFiles()?.forEach { if (it.lastModified() < System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7)) { it.delete() } diff --git a/app/src/main/java/io/legado/app/help/ReadBookConfig.kt b/app/src/main/java/io/legado/app/help/ReadBookConfig.kt index 1a76fc447..3d3049585 100644 --- a/app/src/main/java/io/legado/app/help/ReadBookConfig.kt +++ b/app/src/main/java/io/legado/app/help/ReadBookConfig.kt @@ -368,14 +368,14 @@ object ReadBookConfig { @Suppress("BlockingMethodInNonBlockingContext") ZipUtils.unzipFile(zipFile, FileUtils.createFolderIfNotExist(configDirPath)) val configDir = FileUtils.createFolderIfNotExist(configDirPath) - val configFile = FileUtils.getFile(configDir, "readConfig.json") + val configFile = configDir.getFile("readConfig.json") val config: Config = GSON.fromJsonObject(configFile.readText())!! if (config.textFont.isNotEmpty()) { val fontName = FileUtils.getName(config.textFont) val fontPath = FileUtils.getPath(appCtx.externalFiles, "font", fontName) if (!FileUtils.exist(fontPath)) { - FileUtils.getFile(configDir, fontName).copyTo(File(fontPath)) + configDir.getFile(fontName).copyTo(File(fontPath)) } config.textFont = fontPath } @@ -383,7 +383,7 @@ object ReadBookConfig { val bgName = FileUtils.getName(config.bgStr) val bgPath = FileUtils.getPath(appCtx.externalFiles, "bg", bgName) if (!FileUtils.exist(bgPath)) { - val bgFile = FileUtils.getFile(configDir, bgName) + val bgFile = configDir.getFile(bgName) if (bgFile.exists()) { bgFile.copyTo(File(bgPath)) } @@ -393,7 +393,7 @@ object ReadBookConfig { val bgName = FileUtils.getName(config.bgStrNight) val bgPath = FileUtils.getPath(appCtx.externalFiles, "bg", bgName) if (!FileUtils.exist(bgPath)) { - val bgFile = FileUtils.getFile(configDir, bgName) + val bgFile = configDir.getFile(bgName) if (bgFile.exists()) { bgFile.copyTo(File(bgPath)) } @@ -403,7 +403,7 @@ object ReadBookConfig { val bgName = FileUtils.getName(config.bgStrEInk) val bgPath = FileUtils.getPath(appCtx.externalFiles, "bg", bgName) if (!FileUtils.exist(bgPath)) { - val bgFile = FileUtils.getFile(configDir, bgName) + val bgFile = configDir.getFile(bgName) if (bgFile.exists()) { bgFile.copyTo(File(bgPath)) } diff --git a/app/src/main/java/io/legado/app/help/storage/Backup.kt b/app/src/main/java/io/legado/app/help/storage/Backup.kt index a9c731e6f..631684dab 100644 --- a/app/src/main/java/io/legado/app/help/storage/Backup.kt +++ b/app/src/main/java/io/legado/app/help/storage/Backup.kt @@ -21,7 +21,7 @@ import java.util.concurrent.TimeUnit object Backup { val backupPath: String by lazy { - FileUtils.getFile(appCtx.filesDir, "backup").absolutePath + appCtx.filesDir.getFile("backup").absolutePath } val backupFileNames by lazy { diff --git a/app/src/main/java/io/legado/app/help/storage/ImportOldData.kt b/app/src/main/java/io/legado/app/help/storage/ImportOldData.kt index 6f57f12a5..bcbd4c928 100644 --- a/app/src/main/java/io/legado/app/help/storage/ImportOldData.kt +++ b/app/src/main/java/io/legado/app/help/storage/ImportOldData.kt @@ -5,10 +5,7 @@ import android.net.Uri import androidx.documentfile.provider.DocumentFile import io.legado.app.data.appDb import io.legado.app.help.BookSourceAnalyzer -import io.legado.app.utils.DocumentUtils -import io.legado.app.utils.FileUtils -import io.legado.app.utils.isContentScheme -import io.legado.app.utils.toastOnUi +import io.legado.app.utils.* import java.io.File object ImportOldData { @@ -61,7 +58,7 @@ object ImportOldData { kotlin.runCatching {// Book source val sourceFile = - FileUtils.getFile(file, "myBookSource.json") + file.getFile("myBookSource.json") val json = sourceFile.readText() val importCount = importOldSource(json) context.toastOnUi("成功导入书源${importCount}") @@ -70,7 +67,7 @@ object ImportOldData { } kotlin.runCatching {// Replace rules - val ruleFile = FileUtils.getFile(file, "myBookReplaceRule.json") + val ruleFile = file.getFile("myBookReplaceRule.json") if (ruleFile.exists()) { val json = ruleFile.readText() val importCount = importOldReplaceRule(json) diff --git a/app/src/main/java/io/legado/app/help/storage/Restore.kt b/app/src/main/java/io/legado/app/help/storage/Restore.kt index 5e65be820..0820032d5 100644 --- a/app/src/main/java/io/legado/app/help/storage/Restore.kt +++ b/app/src/main/java/io/legado/app/help/storage/Restore.kt @@ -82,7 +82,7 @@ object Restore { try { val file = File(path) for (fileName in Backup.backupFileNames) { - FileUtils.getFile(file, fileName).let { + file.getFile(fileName).let { if (it.exists()) { it.copyTo( FileUtils.createFileIfNotExist("${Backup.backupPath}${File.separator}$fileName"), diff --git a/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt b/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt index 626a00771..6400267c1 100644 --- a/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt +++ b/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt @@ -64,7 +64,7 @@ object LocalBook { path = uri.toString() val doc = DocumentFile.fromSingleUri(appCtx, uri) doc?.let { - val bookFile = FileUtils.getFile(cacheFolder, it.name!!) + val bookFile = cacheFolder.getFile(it.name!!) if (!bookFile.exists()) { bookFile.createNewFile() doc.readBytes(appCtx)?.let { bytes -> @@ -147,7 +147,7 @@ object LocalBook { fun deleteBook(book: Book, deleteOriginal: Boolean) { kotlin.runCatching { if (book.isLocalTxt() || book.isUmd()) { - val bookFile = FileUtils.getFile(cacheFolder, book.originName) + val bookFile = cacheFolder.getFile(book.originName) bookFile.delete() } if (book.isEpub()) { diff --git a/app/src/main/java/io/legado/app/model/localBook/TextFile.kt b/app/src/main/java/io/legado/app/model/localBook/TextFile.kt index cec006ac0..f00556ca9 100644 --- a/app/src/main/java/io/legado/app/model/localBook/TextFile.kt +++ b/app/src/main/java/io/legado/app/model/localBook/TextFile.kt @@ -264,7 +264,7 @@ class TextFile { private fun getBookFile(book: Book): File { if (book.bookUrl.isContentScheme()) { val uri = Uri.parse(book.bookUrl) - val bookFile = FileUtils.getFile(LocalBook.cacheFolder, book.originName) + val bookFile = LocalBook.cacheFolder.getFile(book.originName) if (!bookFile.exists()) { bookFile.createNewFile() DocumentUtils.readBytes(appCtx, uri)?.let { diff --git a/app/src/main/java/io/legado/app/service/HttpReadAloudService.kt b/app/src/main/java/io/legado/app/service/HttpReadAloudService.kt index 33391dc5f..fbc27b742 100644 --- a/app/src/main/java/io/legado/app/service/HttpReadAloudService.kt +++ b/app/src/main/java/io/legado/app/service/HttpReadAloudService.kt @@ -28,13 +28,13 @@ class HttpReadAloudService : BaseReadAloudService(), private val bdRegex = "^(\\s|\\p{P})+$".toRegex() private val mediaPlayer = MediaPlayer() - private val ttsFolder: String by lazy { - externalCacheDir!!.absolutePath + File.separator + "httpTTS" + private val ttsFolderPath: String by lazy { + externalCacheDir!!.absolutePath + File.separator + "httpTTS" + File.separator } private var task: Coroutine<*>? = null private var playingIndex = -1 private var playIndexJob: Job? = null - private var errorNo = 0 + override fun onCreate() { super.onCreate() @@ -87,6 +87,8 @@ class HttpReadAloudService : BaseReadAloudService(), } } + private var downloadErrorNo: Int = 0 + private fun downloadAudio() { task?.cancel() task = execute { @@ -140,12 +142,13 @@ class HttpReadAloudService : BaseReadAloudService(), playAudio(fis.fd) } } + downloadErrorNo = 0 } catch (e: CancellationException) { //任务取消,不处理 } catch (e: SocketTimeoutException) { removeSpeakCacheFile(fileName) - errorNo++ - if (errorNo > 5) { + downloadErrorNo++ + if (playErrorNo > 5) { createSilentSound(fileName) } else { toastOnUi("tts接口超时,尝试重新获取") @@ -188,7 +191,6 @@ class HttpReadAloudService : BaseReadAloudService(), } } - private fun speakFilePath() = ttsFolder + File.separator private fun md5SpeakFileName(url: String, ttsConfig: String, content: String): String { return MD5Utils.md5Encode16(textChapter!!.title) + "_" + MD5Utils.md5Encode16("$url-|-$ttsConfig-|-$content") } @@ -199,26 +201,26 @@ class HttpReadAloudService : BaseReadAloudService(), } private fun hasSpeakFile(name: String) = - FileUtils.exist("${speakFilePath()}$name.mp3") + FileUtils.exist("${ttsFolderPath}$name.mp3") private fun hasSpeakCacheFile(name: String) = - FileUtils.exist("${speakFilePath()}$name.mp3.cache") + FileUtils.exist("${ttsFolderPath}$name.mp3.cache") private fun createSpeakCacheFile(name: String): File = - FileUtils.createFileWithReplace("${speakFilePath()}$name.mp3.cache") + FileUtils.createFileWithReplace("${ttsFolderPath}$name.mp3.cache") private fun removeSpeakCacheFile(name: String) { - FileUtils.delete("${speakFilePath()}$name.mp3.cache") + FileUtils.delete("${ttsFolderPath}$name.mp3.cache") } private fun getSpeakFileAsMd5(name: String): File = - FileUtils.getFile(File(speakFilePath()), "$name.mp3") + File("${ttsFolderPath}$name.mp3") private fun createSpeakFileAsMd5IfNotExist(name: String): File = - FileUtils.createFileIfNotExist("${speakFilePath()}$name.mp3") + FileUtils.createFileIfNotExist("${ttsFolderPath}$name.mp3") private fun removeCacheFile() { - FileUtils.listDirsAndFiles(speakFilePath())?.forEach { + FileUtils.listDirsAndFiles(ttsFolderPath)?.forEach { if (Regex(""".+\.mp3$""").matches(it.name)) { //mp3缓存文件 val reg = """^${MD5Utils.md5Encode16(textChapter!!.title)}_[a-z0-9]{16}\.mp3$""".toRegex() @@ -293,14 +295,16 @@ class HttpReadAloudService : BaseReadAloudService(), upPlayPos() } + private var playErrorNo = 0 + override fun onError(mp: MediaPlayer?, what: Int, extra: Int): Boolean { if (what == -38 && extra == 0) { play() return true } AppLog.put("朗读错误,($what, $extra)") - errorNo++ - if (errorNo >= 5) { + playErrorNo++ + if (playErrorNo >= 5) { toastOnUi("朗读连续5次错误, 最后一次错误代码($what, $extra)") ReadAloud.pause(this) } else { @@ -310,7 +314,7 @@ class HttpReadAloudService : BaseReadAloudService(), } override fun onCompletion(mp: MediaPlayer?) { - errorNo = 0 + playErrorNo = 0 playNext() } diff --git a/app/src/main/java/io/legado/app/ui/about/AboutFragment.kt b/app/src/main/java/io/legado/app/ui/about/AboutFragment.kt index 29e14471e..ab158dca6 100644 --- a/app/src/main/java/io/legado/app/ui/about/AboutFragment.kt +++ b/app/src/main/java/io/legado/app/ui/about/AboutFragment.kt @@ -125,7 +125,7 @@ class AboutFragment : PreferenceFragmentCompat() { private fun showCrashLogs() { context?.externalCacheDir?.let { exCacheDir -> - val crashDir = FileUtils.getFile(exCacheDir, "crash") + val crashDir = exCacheDir.getFile("crash") val crashLogs = crashDir.listFiles() val crashLogNames = arrayListOf() crashLogs?.forEach { diff --git a/app/src/main/java/io/legado/app/utils/FileExtensions.kt b/app/src/main/java/io/legado/app/utils/FileExtensions.kt new file mode 100644 index 000000000..31f03c04c --- /dev/null +++ b/app/src/main/java/io/legado/app/utils/FileExtensions.kt @@ -0,0 +1,13 @@ +package io.legado.app.utils + +import java.io.File + +fun File.getFile(vararg subDirFiles: String): File { + val path = FileUtils.getPath(this, *subDirFiles) + return File(path) +} + +fun File.exists(vararg subDirFiles: String): Boolean { + return getFile(*subDirFiles).exists() +} + diff --git a/app/src/main/java/io/legado/app/utils/FileUtils.kt b/app/src/main/java/io/legado/app/utils/FileUtils.kt index 2e109a188..81facf72d 100644 --- a/app/src/main/java/io/legado/app/utils/FileUtils.kt +++ b/app/src/main/java/io/legado/app/utils/FileUtils.kt @@ -14,10 +14,6 @@ import java.util.regex.Pattern @Suppress("unused", "MemberVisibilityCanBePrivate") object FileUtils { - fun exists(root: File, vararg subDirFiles: String): Boolean { - return getFile(root, *subDirFiles).exists() - } - fun createFileIfNotExist(root: File, vararg subDirFiles: String): File { val filePath = getPath(root, *subDirFiles) return createFileIfNotExist(filePath) @@ -71,9 +67,17 @@ object FileUtils { return file } - fun getFile(root: File, vararg subDirFiles: String): File { - val filePath = getPath(root, *subDirFiles) - return File(filePath) + fun getPath(rootPath: String, vararg subDirFiles: String): String { + val path = StringBuilder(rootPath) + subDirFiles.forEach { + if (it.isNotEmpty()) { + if (!path.endsWith(File.separator)) { + path.append(File.separator) + } + path.append(it) + } + } + return path.toString() } fun getPath(root: File, vararg subDirFiles: String): String {