diff --git a/app/src/main/java/io/legado/app/help/book/BookExtensions.kt b/app/src/main/java/io/legado/app/help/book/BookExtensions.kt index ee48ddf4a..3eb78ab11 100644 --- a/app/src/main/java/io/legado/app/help/book/BookExtensions.kt +++ b/app/src/main/java/io/legado/app/help/book/BookExtensions.kt @@ -69,7 +69,7 @@ fun Book.getLocalUri(): Uri { Uri.fromFile(File(bookUrl)) } //先检测uri是否有效,这个比较快 - uri.inputStream(appCtx)?.use { + uri.inputStream(appCtx).getOrNull()?.use { localUriCache[bookUrl] = uri }?.let { return uri 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 1a9dd0feb..c4fc91c84 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 @@ -43,10 +43,11 @@ object LocalBook { fun getBookInputStream(book: Book): InputStream { val uri = book.getLocalUri() //文件不存在 尝试下载webDav文件 - val inputStream = uri.inputStream(appCtx) ?: let { - book.removeLocalUriCache() - downloadRemoteBook(book) - } + val inputStream = uri.inputStream(appCtx).getOrNull() + ?: let { + book.removeLocalUriCache() + downloadRemoteBook(book) + } if (inputStream != null) return inputStream book.removeLocalUriCache() throw FileNotFoundException("${uri.path} 文件不存在") @@ -241,7 +242,12 @@ object LocalBook { ?: throw NoStackTraceException("没有设置书籍保存位置!") val bytes = when { str.isAbsUrl() -> AnalyzeUrl(str, source = source).getInputStream() - str.isDataUrl() -> ByteArrayInputStream(Base64.decode(str.substringAfter("base64,"), Base64.DEFAULT)) + str.isDataUrl() -> ByteArrayInputStream( + Base64.decode( + str.substringAfter("base64,"), + Base64.DEFAULT + ) + ) else -> throw NoStackTraceException("在线导入书籍支持http/https/DataURL") } return saveBookFile(bytes, fileName) @@ -324,7 +330,7 @@ object LocalBook { localBook.bookUrl = if (it.isContentScheme()) it.toString() else it.path!! localBook.save() localBook.cacheLocalUri(it) - it.inputStream(appCtx) + it.inputStream(appCtx).getOrThrow() } } catch (e: Exception) { e.printOnDebug() diff --git a/app/src/main/java/io/legado/app/ui/association/BaseAssociationViewModel.kt b/app/src/main/java/io/legado/app/ui/association/BaseAssociationViewModel.kt index 9e36dd7f6..b12b55def 100644 --- a/app/src/main/java/io/legado/app/ui/association/BaseAssociationViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/association/BaseAssociationViewModel.kt @@ -15,7 +15,7 @@ abstract class BaseAssociationViewModel(application: Application) : BaseViewMode fun importJson(uri: Uri) { when { - uri.inputStream(context).contains("bookSourceUrl") -> + uri.inputStream(context).getOrNull().contains("bookSourceUrl") -> successLive.postValue(Pair("bookSource", uri.toString())) else -> importJson(uri.readText(context)) } diff --git a/app/src/main/java/io/legado/app/ui/association/FileAssociationViewModel.kt b/app/src/main/java/io/legado/app/ui/association/FileAssociationViewModel.kt index ca484936b..afa774b8e 100644 --- a/app/src/main/java/io/legado/app/ui/association/FileAssociationViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/association/FileAssociationViewModel.kt @@ -23,7 +23,7 @@ class FileAssociationViewModel(application: Application) : BaseAssociationViewMo val fileDoc = FileDoc.fromUri(uri, false) fileName = fileDoc.name kotlin.runCatching { - if (uri.inputStream(context).isJson()) { + if (uri.inputStream(context).getOrNull().isJson()) { importJson(uri) return@execute } diff --git a/app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt b/app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt index be5341cfb..29f457496 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt @@ -112,7 +112,7 @@ class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) { } mText.isUri() -> { val uri = Uri.parse(mText) - uri.inputStream(context)?.let { + uri.inputStream(context).getOrThrow().let { allSources.addAll(BookSource.fromJsonArray(it).getOrThrow()) } } diff --git a/app/src/main/java/io/legado/app/ui/book/group/GroupEditDialog.kt b/app/src/main/java/io/legado/app/ui/book/group/GroupEditDialog.kt index c50b73bfc..98f20d0ca 100644 --- a/app/src/main/java/io/legado/app/ui/book/group/GroupEditDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/group/GroupEditDialog.kt @@ -12,6 +12,7 @@ import io.legado.app.lib.dialogs.alert import io.legado.app.lib.theme.primaryColor import io.legado.app.utils.* import io.legado.app.utils.viewbindingdelegate.viewBinding +import splitties.init.appCtx import splitties.views.onClick import java.io.FileOutputStream @@ -27,17 +28,23 @@ class GroupEditDialog() : BaseDialogFragment(R.layout.dialog_book_group_edit) { private val viewModel by viewModels() private var bookGroup: BookGroup? = null val selectImage = registerForActivityResult(SelectImageContract()) { - readUri(it?.uri) { fileDoc, inputStream -> - var file = requireContext().externalFiles - val suffix = fileDoc.name.substringAfterLast(".") - val fileName = it.uri!!.inputStream(requireContext())!!.use { - MD5Utils.md5Encode(it) + ".$suffix" + it ?: return@registerForActivityResult + it.uri ?: return@registerForActivityResult + readUri(it.uri) { fileDoc, inputStream -> + try { + var file = requireContext().externalFiles + val suffix = fileDoc.name.substringAfterLast(".") + val fileName = it.uri.inputStream(requireContext()).getOrThrow().use { tmp -> + MD5Utils.md5Encode(tmp) + ".$suffix" + } + file = FileUtils.createFileIfNotExist(file, "covers", fileName) + FileOutputStream(file).use { outputStream -> + inputStream.copyTo(outputStream) + } + binding.ivCover.load(file.absolutePath) + } catch (e: Exception) { + appCtx.toastOnUi(e.localizedMessage) } - file = FileUtils.createFileIfNotExist(file, "covers", fileName) - FileOutputStream(file).use { outputStream -> - inputStream.copyTo(outputStream) - } - binding.ivCover.load(file.absolutePath) } } diff --git a/app/src/main/java/io/legado/app/ui/book/info/edit/BookInfoEditActivity.kt b/app/src/main/java/io/legado/app/ui/book/info/edit/BookInfoEditActivity.kt index 220089383..fb6e13c79 100644 --- a/app/src/main/java/io/legado/app/ui/book/info/edit/BookInfoEditActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/info/edit/BookInfoEditActivity.kt @@ -17,6 +17,7 @@ import io.legado.app.help.book.isLocal import io.legado.app.ui.book.changecover.ChangeCoverDialog import io.legado.app.utils.* import io.legado.app.utils.viewbindingdelegate.viewBinding +import splitties.init.appCtx import java.io.FileOutputStream class BookInfoEditActivity : @@ -120,17 +121,21 @@ class BookInfoEditActivity : private fun coverChangeTo(uri: Uri) { readUri(uri) { fileDoc, inputStream -> - inputStream.use { - var file = this.externalFiles - val suffix = fileDoc.name.substringAfterLast(".") - val fileName = uri.inputStream(this)!!.use { - MD5Utils.md5Encode(it) + ".$suffix" + runCatching { + inputStream.use { + var file = this.externalFiles + val suffix = fileDoc.name.substringAfterLast(".") + val fileName = uri.inputStream(this).getOrThrow().use { + MD5Utils.md5Encode(it) + ".$suffix" + } + file = FileUtils.createFileIfNotExist(file, "covers", fileName) + FileOutputStream(file).use { outputStream -> + inputStream.copyTo(outputStream) + } + coverChangeTo(file.absolutePath) } - file = FileUtils.createFileIfNotExist(file, "covers", fileName) - FileOutputStream(file).use { outputStream -> - inputStream.copyTo(outputStream) - } - coverChangeTo(file.absolutePath) + }.onFailure { + appCtx.toastOnUi(it.localizedMessage) } } } diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt index c125230a6..505f1be53 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt @@ -34,6 +34,7 @@ import io.legado.app.ui.document.HandleFileContract import io.legado.app.ui.widget.seekbar.SeekBarChangeListener import io.legado.app.utils.* import io.legado.app.utils.viewbindingdelegate.viewBinding +import splitties.init.appCtx import java.io.File import java.io.FileOutputStream @@ -353,17 +354,21 @@ class BgTextConfigDialog : BaseDialogFragment(R.layout.dialog_read_bg_text) { private fun setBgFromUri(uri: Uri) { readUri(uri) { fileDoc, inputStream -> - var file = requireContext().externalFiles - val suffix = fileDoc.name.substringAfterLast(".") - val fileName = uri.inputStream(requireContext())!!.use { - MD5Utils.md5Encode(it) + ".$suffix" + kotlin.runCatching { + var file = requireContext().externalFiles + val suffix = fileDoc.name.substringAfterLast(".") + val fileName = uri.inputStream(requireContext()).getOrThrow().use { + MD5Utils.md5Encode(it) + ".$suffix" + } + file = FileUtils.createFileIfNotExist(file, "bg", fileName) + FileOutputStream(file).use { outputStream -> + inputStream.copyTo(outputStream) + } + ReadBookConfig.durConfig.setCurBg(2, file.absolutePath) + postEvent(EventBus.UP_CONFIG, false) + }.onFailure { + appCtx.toastOnUi(it.localizedMessage) } - file = FileUtils.createFileIfNotExist(file, "bg", fileName) - FileOutputStream(file).use { outputStream -> - inputStream.copyTo(outputStream) - } - ReadBookConfig.durConfig.setCurBg(2, file.absolutePath) - postEvent(EventBus.UP_CONFIG, false) } } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/config/CoverConfigFragment.kt b/app/src/main/java/io/legado/app/ui/config/CoverConfigFragment.kt index 1866b5edb..0ff57e78c 100644 --- a/app/src/main/java/io/legado/app/ui/config/CoverConfigFragment.kt +++ b/app/src/main/java/io/legado/app/ui/config/CoverConfigFragment.kt @@ -14,6 +14,7 @@ import io.legado.app.lib.prefs.fragment.PreferenceFragment import io.legado.app.lib.theme.primaryColor import io.legado.app.model.BookCover import io.legado.app.utils.* +import splitties.init.appCtx import java.io.FileOutputStream class CoverConfigFragment : PreferenceFragment(), @@ -139,17 +140,21 @@ class CoverConfigFragment : PreferenceFragment(), private fun setCoverFromUri(preferenceKey: String, uri: Uri) { readUri(uri) { fileDoc, inputStream -> - var file = requireContext().externalFiles - val suffix = fileDoc.name.substringAfterLast(".") - val fileName = uri.inputStream(requireContext())!!.use { - MD5Utils.md5Encode(it) + ".$suffix" + kotlin.runCatching { + var file = requireContext().externalFiles + val suffix = fileDoc.name.substringAfterLast(".") + val fileName = uri.inputStream(requireContext()).getOrThrow().use { + MD5Utils.md5Encode(it) + ".$suffix" + } + file = FileUtils.createFileIfNotExist(file, "covers", fileName) + FileOutputStream(file).use { + inputStream.copyTo(it) + } + putPrefString(preferenceKey, file.absolutePath) + BookCover.upDefaultCover() + }.onFailure { + appCtx.toastOnUi(it.localizedMessage) } - file = FileUtils.createFileIfNotExist(file, "covers", fileName) - FileOutputStream(file).use { - inputStream.copyTo(it) - } - putPrefString(preferenceKey, file.absolutePath) - BookCover.upDefaultCover() } } diff --git a/app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt b/app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt index a38f71d5c..d2883a131 100644 --- a/app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt +++ b/app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt @@ -30,6 +30,7 @@ import io.legado.app.lib.theme.primaryColor import io.legado.app.ui.widget.number.NumberPickerDialog import io.legado.app.ui.widget.seekbar.SeekBarChangeListener import io.legado.app.utils.* +import splitties.init.appCtx import java.io.FileOutputStream @@ -303,17 +304,21 @@ class ThemeConfigFragment : PreferenceFragment(), private fun setBgFromUri(uri: Uri, preferenceKey: String, success: () -> Unit) { readUri(uri) { fileDoc, inputStream -> - var file = requireContext().externalFiles - val suffix = fileDoc.name.substringAfterLast(".") - val fileName = uri.inputStream(requireContext())!!.use { - MD5Utils.md5Encode(it) + ".$suffix" + kotlin.runCatching { + var file = requireContext().externalFiles + val suffix = fileDoc.name.substringAfterLast(".") + val fileName = uri.inputStream(requireContext()).getOrThrow().use { + MD5Utils.md5Encode(it) + ".$suffix" + } + file = FileUtils.createFileIfNotExist(file, preferenceKey, fileName) + FileOutputStream(file).use { + inputStream.copyTo(it) + } + putPrefString(preferenceKey, file.absolutePath) + success() + }.onFailure { + appCtx.toastOnUi(it.localizedMessage) } - file = FileUtils.createFileIfNotExist(file, preferenceKey, fileName) - FileOutputStream(file).use { - inputStream.copyTo(it) - } - putPrefString(preferenceKey, file.absolutePath) - success() } } diff --git a/app/src/main/java/io/legado/app/ui/config/WelcomeConfigFragment.kt b/app/src/main/java/io/legado/app/ui/config/WelcomeConfigFragment.kt index 680890c9b..20af1bceb 100644 --- a/app/src/main/java/io/legado/app/ui/config/WelcomeConfigFragment.kt +++ b/app/src/main/java/io/legado/app/ui/config/WelcomeConfigFragment.kt @@ -13,6 +13,7 @@ import io.legado.app.lib.prefs.fragment.PreferenceFragment import io.legado.app.lib.theme.primaryColor import io.legado.app.model.BookCover import io.legado.app.utils.* +import splitties.init.appCtx import java.io.FileOutputStream class WelcomeConfigFragment : PreferenceFragment(), @@ -119,16 +120,20 @@ class WelcomeConfigFragment : PreferenceFragment(), private fun setCoverFromUri(preferenceKey: String, uri: Uri) { readUri(uri) { fileDoc, inputStream -> - var file = requireContext().externalFiles - val suffix = fileDoc.name.substringAfterLast(".") - val fileName = uri.inputStream(requireContext())!!.use { - MD5Utils.md5Encode(it) + ".$suffix" + kotlin.runCatching { + var file = requireContext().externalFiles + val suffix = fileDoc.name.substringAfterLast(".") + val fileName = uri.inputStream(requireContext()).getOrThrow().use { + MD5Utils.md5Encode(it) + ".$suffix" + } + file = FileUtils.createFileIfNotExist(file, "covers", fileName) + FileOutputStream(file).use { + inputStream.copyTo(it) + } + putPrefString(preferenceKey, file.absolutePath) + }.onFailure { + appCtx.toastOnUi(it.localizedMessage) } - file = FileUtils.createFileIfNotExist(file, "covers", fileName) - FileOutputStream(file).use { - inputStream.copyTo(it) - } - putPrefString(preferenceKey, file.absolutePath) } } diff --git a/app/src/main/java/io/legado/app/utils/UriExtensions.kt b/app/src/main/java/io/legado/app/utils/UriExtensions.kt index 1c1fa6cc3..7f9b19bd4 100644 --- a/app/src/main/java/io/legado/app/utils/UriExtensions.kt +++ b/app/src/main/java/io/legado/app/utils/UriExtensions.kt @@ -173,23 +173,28 @@ fun Uri.writeBytes( return false } -fun Uri.inputStream(context: Context): InputStream? { +fun Uri.inputStream(context: Context): Result { val uri = this - try { - if (isContentScheme()) { - val doc = DocumentFile.fromSingleUri(context, uri) - doc ?: throw NoStackTraceException("未获取到文件") - return context.contentResolver.openInputStream(uri)!! - } else { - RealPathUtil.getPath(context, uri)?.let { path -> + return kotlin.runCatching { + try { + if (isContentScheme()) { + DocumentFile.fromSingleUri(context, uri) + ?: throw NoStackTraceException("未获取到文件") + return@runCatching context.contentResolver.openInputStream(uri)!! + } else { + val path = RealPathUtil.getPath(context, uri) + ?: throw NoStackTraceException("未获取到文件") val file = File(path) - return FileInputStream(file) + if (file.exists()) { + return@runCatching FileInputStream(file) + } else { + throw NoStackTraceException("文件不存在") + } } + } catch (e: Exception) { + e.printOnDebug() + AppLog.put("读取inputStream失败:${e.localizedMessage}", e) + throw e } - } catch (e: Exception) { - e.printOnDebug() - context.toastOnUi("读取inputStream失败:${e.localizedMessage}") - AppLog.put("读取inputStream失败:${e.localizedMessage}", e) } - return null } \ No newline at end of file